const svg = d3.select("svg") const defaultColor = "#555555" const languages = { tamil: {name: "Tamil", color: "#75d795", code: "ta", districts: []}, malayalam: {name: "Malayalam", color: "#ff7c7c", code: "ml", districts: []}, kannada: {name: "Kannada", color: "#ffe77c", code: "kn", districts: []}, telugu: {name: "Telugu", color: "#7c9dff", code: "te", districts: []}, marathi: {name: "Marathi", color: "#e0ff7c", code: "mr", districts: []}, konkani: {name: "Konkani", color: "#9b7cff", code: "gom", districts: []}, hindi: {name: "Hindi", color: "#d17cff", code: "hi", districts: []}, gujarati: {name: "Gujarati", color: "#7cffee", code: "gu", districts: []}, oriya: {name: "Oriya", color: "#9bcc9f", code: "or", districts: []}, bengali: {name: "Bengali", color: "#bf9a77", code: "bn", districts: []}, punjabi: {name: "Punjabi", color: "#e84a35", code: "pa", districts: []}, mizo: {name: "Mizo", color: "#a6a4de", code: "lus", districts: []}, assamese: {name: "Assamese", color: "#c9535b", code: "as", districts: []}, bhojpuri: {name: "Bhojpuri", color: "#b3b876", code: "bho", districts: []}, manipuri: {name: "Manipuri", color: "#c9afad", code: "mni-Mtei", districts: []}, dogri: {name: "Dogri", color: "#9595e6", code: "doi", districts: []}, nepali: {name: "Nepali", color: "#71998e", code: "ne", districts: []}, urdu: {name: "Urdu", color: "#3fa179", code: "ur", districts: []}, tulu: {name: "Tulu", color: "#dedc52", code: "tcy", districts: []}, maithali: {name: "Maithali", color: "#4472a6", code: "mai", districts: []}, santali: {name: "Santali", color: "#96bf60", code: "sat", districts: []}, sindhi: {name: "Sindhi", color: "#e89931", code: "sd", districts: []}, awadhi: {name: "Awadhi", color: "#847fb5", code: "awa", districts: []}, }; // Credit: https://www.artcraftblend.com/blogs/colors/shades-of-pastel const state2lang = { "Tamil Nadu": languages["tamil"], "Kerala": languages["malayalam"], "Karnataka": languages["kannada"], "Andhra Pradesh": languages["telugu"], "Telangana": languages["telugu"], "Maharashtra": languages["marathi"], "Goa": languages["konkani"], "Odisha": languages["oriya"], "Gujarat": languages["gujarati"], "Rajasthan": languages["hindi"], "Chhattisgarh": languages["hindi"], "Jharkhand": languages["hindi"], // DEFAULT "West Bengal": languages["bengali"], "Assam": languages["assamese"], "Tripura": languages["bengali"], "Mizoram": languages["mizo"], "Manipur": languages["manipuri"], "Sikkim": languages["nepali"], "Bihar": languages["bhojpuri"], "Madhya Pradesh": languages["hindi"], "Uttar Pradesh": languages["hindi"], "Uttarakhand": languages["hindi"], // DEFAULT "Haryana": languages["hindi"], // DEFAULT "Punjab": languages["punjabi"], "Himachal Pradesh": languages["hindi"], // DEFAULT "Ladakh": languages["dogri"], "Jammu and Kashmir": languages["dogri"], "Dadra and Nagar Haveli and Daman and Diu": languages["gujarati"], "Puducherry": languages["tamil"], "Lakshadweep": languages["malayalam"], "Delhi": languages["hindi"], "Chandigarh": languages["hindi"] } const district2lang = { // Should override state colors "Dakshina Kannada": languages["tulu"], "Muzaffarpur": languages["maithali"], "West Champaran": languages["maithali"], "East Champaran": languages["maithali"], "Vaishali": languages["maithali"], "Sitamarhi": languages["maithali"], "Sheohar": languages["maithali"], "Saharsa": languages["maithali"], "Madhepura": languages["maithali"], "Supaul": languages["maithali"], "Araria": languages["maithali"], "Katihar": languages["maithali"], "Kishanganj": languages["maithali"], "Purnia": languages["maithali"], "Banka": languages["maithali"], "Bhagalpur": languages["maithali"], "Munger": languages["maithali"], "Begusarai": languages["maithali"], "Jamui": languages["maithali"], "Khagaria": languages["maithali"], "Sheikhpura": languages["maithali"], "Lakhisarai": languages["maithali"], "Godda": languages["maithali"], "Deoghar": languages["maithali"], "Dumka": languages["maithali"], "Jamtara": languages["maithali"], "Sahibganj": languages["maithali"], "Pakur": languages["maithali"], "Darbhanga": languages["maithali"], "Madhubani": languages["maithali"], "Samastipur": languages["maithali"], "Moradabad": languages["urdu"], "Rampur": languages["urdu"], "Bijnor": languages["urdu"], "Amroha": languages["urdu"], "Meerut": languages["urdu"], "Ghaziabad": languages["urdu"], "Bulandshahr": languages["urdu"], "Aligarh": languages["urdu"], "Budaun": languages["urdu"], "Bareilly": languages["urdu"], "Sambhal": languages["urdu"], "Muzaffarnagar": languages["urdu"], "Saharanpur": languages["urdu"], "Shamli": languages["urdu"], "Hapur": languages["urdu"], "Kutch": languages["sindhi"], "Godda": languages["santali"], "Deoghar": languages["santali"], "Dumka": languages["santali"], "Jamtara": languages["santali"], "Sahibganj": languages["santali"], "Pakur": languages["santali"], "East Singhbhum": languages["santali"], "Jhargram": languages["santali"], "Bankura": languages["santali"], "Purulia": languages["santali"], "Kanpur": languages["awadhi"], "Lakhimpur Kheri": languages["awadhi"], "Sitapur": languages["awadhi"], "Hardoi": languages["awadhi"], "Unnao": languages["awadhi"], "Fatehpur": languages["awadhi"], "Barabanki": languages["awadhi"], "Lucknow": languages["awadhi"], "Rae Bareli": languages["awadhi"], "Amethi": languages["awadhi"], "Bahraich": languages["awadhi"], } // Functions for calculating and dealing with language boundaries function reverseCoordArrays(coords) { if (!Array.isArray(coords)) { return coords; } if (coords.every(item => Array.isArray(item) && item.length == 2 && item.every(val => Number.isFinite(val)))) { if (!turf.booleanClockwise(coords)) { return coords.reverse(); } else { return coords; } } return coords.map(reverseCoordArrays); } function getOuterBoundaryPolygon(features) { // Check if we have features to process if (!features || features.length === 0) { console.warn("No features to process for boundary"); return null; } // Handle single feature case if (features.length === 1) { return features[0]; } let combined = turf.union(turf.featureCollection(features)) combined.geometry.coordinates = reverseCoordArrays(combined.geometry.coordinates); return combined; } function district2langFunc(d) { if (district2lang.hasOwnProperty(d.properties.district)) { return district2lang[d.properties.district]; } else if (state2lang.hasOwnProperty(d.properties.st_nm)) { return state2lang[d.properties.st_nm]; } else { return undefined; } } function stateOrDistrictOrLanguage(d) { if (typeof d.properties.district !== 'undefined') { return "district" } else { if (typeof d.properties.lang_name !== 'undefined') { return "language" } else { return "state" } } } function drawMap(world) { const mapWidth = document.getElementById("indiaMap").getAttribute("width") const mapHeight = document.getElementById("indiaMap").getAttribute("height") const projection = d3.geoMercator().fitSize([mapWidth, mapHeight], world) const path = d3.geoPath().projection(projection); const states = svg.selectAll("g") .data(world.features) .enter() .append("g"); states.append("path") .attr("d", path) .attr("class", d => stateOrDistrictOrLanguage(d)) .attr("fill", function(d) { if (stateOrDistrictOrLanguage(d) === "language") { return languages[d.properties.lang_name.toLowerCase()].color; } }) .each(function(d) { if (stateOrDistrictOrLanguage(d) === "district") { const districtLang = district2langFunc(d); if (typeof districtLang !== 'undefined') { districtLang.districts.push(d) } } // Hide map load spinner after map has loaded document.getElementById("mapLoadSpinner").classList.add("hide"); document.querySelector("svg").classList.add("show"); }) .append("title") // Tooltip .text(d => d.properties.district); states.append("text") .attr("x", function(d) { if (stateOrDistrictOrLanguage(d) == "language") { rtv = projection(d3.geoCentroid(d))[0]; if (d.properties.lang_name == "Kannada") { rtv -= 20; } if (d.properties.lang_name == "Tamil") { rtv += 20; } if (d.properties.lang_name == "Maithali") { rtv += 10; } if (d.properties.lang_name == "Konkani") { rtv -= 15; } return rtv } }) .attr("y", function(d) { if (stateOrDistrictOrLanguage(d) == "language") { rtv = projection(d3.geoCentroid(d))[1] if (d.properties.lang_name == "Kannada") { rtv += 15; } if (d.properties.lang_name == "Tamil") { rtv -= 20; } if (d.properties.lang_name == "Gujarati") { rtv -= 10; } if (d.properties.lang_name == "Mizo") { rtv += 20; } if (d.properties.lang_name == "Nepali") { rtv -= 10; } return rtv } }) .attr("text-anchor", "middle") .attr("fill", "black") .attr("class", "translationText") .attr("id", function(d) { if (stateOrDistrictOrLanguage(d) == "language") { return d.properties.lang_code+"Text" } else { d3.select(this).remove() } }) .text(function(d) { if (stateOrDistrictOrLanguage(d) == "language") { return d.properties.lang_name; } else { d3.select(this).remove() // Only add this attribute if the element is a language } }); // Romanization states.append("text") .attr("x", d => stateOrDistrictOrLanguage(d) == "language" ? document.getElementById(d.properties.lang_code + "Text").getAttribute("x") : projection(d3.geoCentroid(d))[0]) .attr("y", d => stateOrDistrictOrLanguage(d) == "language" ? parseFloat(document.getElementById(d.properties.lang_code + "Text").getAttribute("y")) + parseFloat(getComputedStyle(document.getElementsByClassName('translationText')[0]).getPropertyValue('font-size')) : projection(d3.geoCentroid(d))[1]) .attr("text-anchor", "middle") .attr("fill", "black") .attr("class", "romanizationText") .attr("id", function(d) { if (stateOrDistrictOrLanguage(d) == "language") { return d.properties.lang_code+"Romanization" } else { d3.select(this).remove() } }) .each(function(d) { if (!stateOrDistrictOrLanguage(d) == "language") { d3.select(this).remove() // Only add this attribute if the element is a language } }); // Language states.append("text") .attr("x", d => stateOrDistrictOrLanguage(d) == "language" ? document.getElementById(d.properties.lang_code + "Text").getAttribute("x") : projection(d3.geoCentroid(d))[0]) .attr("y", d => stateOrDistrictOrLanguage(d) == "language" ? parseFloat(document.getElementById(d.properties.lang_code + "Text").getAttribute("y")) - parseFloat(getComputedStyle(document.getElementsByClassName('translationText')[0]).getPropertyValue('font-size')) : projection(d3.geoCentroid(d))[1]) .attr("text-anchor", "middle") .attr("fill", "black") .attr("class", "languageText") .attr("id", function(d) { if (stateOrDistrictOrLanguage(d) == "language") { return d.properties.lang_code+"Language" } else { d3.select(this).remove() } }) .each(function(d) { if (!stateOrDistrictOrLanguage(d) == "language") { d3.select(this).remove() // Only add this attribute if the element is a language } }) .text(function(d) { if (stateOrDistrictOrLanguage(d) == "language") { return d.properties.lang_name; } else { d3.select(this).remove() // Only add this attribute if the element is a language } }) let allLangs = [] const coordinates = [77.69916967457782,23.389970772934166]; const [xCoord, yCoord] = projection(coordinates); // svg.append("text") // .attr("x", xCoord) // .attr("y", yCoord) // .attr("class", "testClass") // .attr("text-anchor", "middle") // .attr("font-size", "12px") // .attr("fill", "black") // .text("Hello, Map!"); // for (const [langId,lang] of Object.entries(languages)) { // let geojson = { // "type": "FeatureCollection", // "features": lang.districts // }; // // let outerBound = getOuterBoundaryPolygon(geojson.features) // outerBound["id"] = "lang" + lang.name // outerBound.properties["lang_name"]= lang.name // outerBound.properties["lang_code"]= lang.code // allLangs.push(outerBound); // // svg.append("path") // .datum(outerBound) // .attr("d", path) // .attr("fill", "none") // .attr("stroke", "red") // .attr("stroke-width", 2) // } // console.log(JSON.stringify(allLangs)) } d3.json("india_with_districts_with_languages_min.json").then(drawMap)