PageSourceSearch

https://ecozonas.org/static/dashboard/components/mappings-gender-security-stats/component.js?v=1.3.0

js ecozonas.org collected 2026-10-04 08:12:41 UTC 6,045 bytes, 215 lines download raw bytes

1class MappingsGenderSecurityStats extends HTMLElement {
2  static get observedAttributes() {
3    return [];
4  }
5
6  constructor() {
7    super();
8    const template = document.getElementById('mappings-gender-security-stats-template').content;
9    this.attachShadow({ mode: 'open' });
10    this.shadowRoot.appendChild(template.cloneNode(true));
11
12    this._mappings = [];
13    this._graph;
14    this.i18n = JSON.parse(this.shadowRoot.getElementById("i18n").textContent);
15  }
16
17  render() {
18    if (this._mappings.length > 0) {
19      if(this._graph) {
20        this.updateGraphData(this.calculateData());
21      } else {
22        this.drawGraph(this.calculateData());
23      }
24    } else {
25      // En el caso de que no haya mapeos, mostrar mensaje por defecto
26      this.drawNoData();
27    }
28  }
29
30  calculateData() {
31    const root = document.documentElement;
32
33    const MUJER = 'MUJER';
34    const HOMBRE = 'HOMBRE';
35    let mujeres = 0;
36    let hombres = 0;
37    let otros = 0;
38
39    const data = {
40      labels: [
41        this.i18n.RobberyDay,
42        this.i18n.HarassmentDay,
43        this.i18n.RobberyNight,
44        this.i18n.HarassmentNight,
45        this.i18n.AllwaysUnsafe,
46      ],
47      datasets: [
48        {
49          label: this.i18n.Women,
50          data: [0, 0, 0, 0, 0],
51          backgroundColor: getComputedStyle(root).getPropertyValue('--color-category-7').trim(),
52        },
53        {
54          label: this.i18n.Men,
55          data: [0, 0, 0, 0, 0],
56          backgroundColor: getComputedStyle(root).getPropertyValue('--color-category-6').trim(),
57        },
58        {
59          label: this.i18n.Others,
60          data: [0, 0, 0, 0, 0],
61          backgroundColor: getComputedStyle(root).getPropertyValue('--color-category-5').trim(),
62        },
63      ]
64    }
65
66    this._mappings.forEach((m) => {
67
68      const gender = m.properties.gender;
69      const block = this.getBlockByCode(m.properties.all_blocks, 'SECURITY_PERCEPTION');
70
71      switch(gender) {
72
73        case MUJER:
74        mujeres++;
75        if(block.answer.includes('0')) {
76          data.datasets[0].data[4]++;
77          return; // hack para bloques checkbox con respuesta ninguno
78        }
79        if(block.answer.includes('1')) data.datasets[0].data[0]++;
80        if(block.answer.includes('2')) data.datasets[0].data[2]++;
81        if(block.answer.includes('3')) data.datasets[0].data[1]++;
82        if(block.answer.includes('4')) data.datasets[0].data[3]++;
83        break;
84
85        case HOMBRE:
86        hombres++;
87        if(block.answer.includes('0')) {
88          data.datasets[1].data[4]++;
89          return; // hack para bloques checkbox con respuesta ninguno
90        }
91        if(block.answer.includes('1')) data.datasets[1].data[0]++;
92        if(block.answer.includes('2')) data.datasets[1].data[2]++;
93        if(block.answer.includes('3')) data.datasets[1].data[1]++;
94        if(block.answer.includes('4')) data.datasets[1].data[3]++;
95        break;
96
97        default:
98        otros++;
99        if(block.answer.includes('0')) {
100          data.datasets[2].data[4]++;
101          return; // hack para bloques checkbox con respuesta ninguno
102        }
103        if(block.answer.includes('1')) data.datasets[2].data[0]++;
104        if(block.answer.includes('2')) data.datasets[2].data[2]++;
105        if(block.answer.includes('3')) data.datasets[2].data[1]++;
106        if(block.answer.includes('4')) data.datasets[2].data[3]++;
107      }
108    })
109
110    if(mujeres > 0) {
111      data.datasets[0].data = data.datasets[0].data.map(e => e / mujeres * 100);
112    }
113
114    if(hombres > 0) {
115      data.datasets[1].data = data.datasets[1].data.map(e => e / hombres * 100);
116    }
117
118    if(otros > 0) {
119      data.datasets[2].data = data.datasets[2].data.map(e => e / otros * 100);
120    }
121
122    this.shadowRoot.getElementById('mujeres').innerHTML = mujeres;
123    this.shadowRoot.getElementById('hombres').innerHTML = hombres;
124    this.shadowRoot.getElementById('otros').innerHTML = otros;
125
126    return data;
127  }
128
129  getBlockByCode(blocks, code) {
130    return blocks.find((b) => b.code === code)
131  }
132
133  showGraph() {
134    this.shadowRoot.getElementById('message').classList.add('hidden');
135    this.shadowRoot.getElementById('graph').classList.remove('hidden');
136  }
137
138  showMessage() {
139    this.shadowRoot.getElementById('message').classList.remove('hidden');
140    this.shadowRoot.getElementById('graph').classList.add('hidden');
141  }
142
143  drawNoData() {
144    this.showMessage()
145    if(this._graph) {
146      this._graph.destroy();
147      this._graph = undefined;
148    }
149    this.shadowRoot.getElementById('mujeres').innerHTML = 0;
150    this.shadowRoot.getElementById('hombres').innerHTML = 0;
151    this.shadowRoot.getElementById('otros').innerHTML = 0;
152  }
153
154  updateGraphData(data) {
155    this.showGraph()
156    this._graph.data = data;
157    this._graph.update();
158  }
159
160  drawGraph(data) {
161    this.showGraph();
162
163    this._graph = new Chart(
164      this.shadowRoot.getElementById('graph'),
165      {
166        type: 'bar',
167        data: data,
168        options: {
169          maintainAspectRatio: false,
170          scales: {
171            y: {
172              beginAtZero: true,
173              max: 100,
174              ticks: {
175                callback: function(value) {
176                  return value + "%";
177                }
178              }
179            }
180          },
181          plugins: {
182            title: {
183              display: false
184            },
185            tooltip: {
186              callbacks: {
187                label: function(context) {
188                  let label = context.dataset.label || '';
189                  if (label) {
190                    label += ': ';
191                  }
192                  if (context.parsed.y !== null) {
193                    label += context.parsed.y + '%';
194                  }
195                  return label;
196                }
197              }
198            }
199          }
200        }
201      }
202    );
203  };
204
205  get mappings() {
206    return this._mappings;
207  }
208
209  set mappings(data) {
210    this._mappings = data;
211    this.render();
212  }
213}
214
215customElements.define('mappings-gender-security-stats', MappingsGenderSecurityStats);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.