UNPKG

inegicomponentes-grafica

Version:

Componentes de visualizacion 2023 - Graficas

604 lines (575 loc) 23 kB
/* Defaults.js @descripcion: Objetos con valores por defecto. > OpcionesHighcharts: opciones globales para Highcharts > OpcionesGrafica: objeto de opciones de configuracion del gráfico > ParametrosUsuario: objeto con los parametros de entrada del usuario aceptados por el componente */ import { GRAFICAS } from '../Utilidades/Constantes' import Helper from '../Utilidades/Helper'; // Inicializa Highcharts const OpcionesHighcharts = { time: { timezone: 'America/Mexico' }, title:{text:""}, credits:{ enabled:true, href:"https://www.inegi.org.mx", position:{}, text:"INEGI" }, lang:{ contextButtonTitle:"Opciones", decimalPoint:".", downloadCSV:"Descarga CSV", downloadJPEG:"Descarga JPEG", downloadPDF:"Descarga PDF", downloadPNG:"Descarga PNG", downloadSVG:"Descarga SVG", downloadXLS:"Descarga XLS", exitFullscreen:"Salir de pantalla completa", exportInProgress:"Exportando...", hideData:"Ocultar tabla de datos", loading:"Cargando...", months:["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"], noData:"No hay datos para mostrar", numericSymbolMagnitude:1000, numericSymbols:["k", "M", "G", "T", "P", "E"], playAsSound:"Escuchar sonido", printChart:"Imprimir gráfica", resetZoom:"Reiniciar Zoom", resetZoomTitle:"Zoom 1:1", shortMonths:["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"], shortWeekdays:undefined, thousandsSep:"\u0020", viewData:"Ver tabla de datos", viewFullscreen:"Ver pantalla completa", weekdays:["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sabado"] } } let OpcionesGrafica = { chart:{ style:{ fontFamily:'"Lucida Grande", Verdana', fontSize:'14px' }, height:400, type:"column", animation:true, backgroundColor:"", borderColor:"#d71d2a", inverted:false, panning:{ enabled:true, type:"xy" }, zooming:{zoomType:"xy", pinchType:"xy"}, }, colors:["#264653", "#2a9d8f","#e9c46a","#457b9d","#f9844a","#9e2a2b","#f08080","#3a5a40","#f15bb5","#a3b18a","#f8961e", "#ffe66d", "#55a630", "#2b9348", "#a44a3f", "#a68a64", "#723d46", "#87986a", "#a53860", "#450920", "#f4e285", "#4a5759", "#55828b", "#004e89", "#f2d0a9", "#bfd8bd", "#b2ff9e", "#ece2d0", "#56ab91", "#c81d25", "#ff5400"], // opciones para la carga de datos desde difentes metodos usando la propiedad DATA data: { // >>> grafica dede un archivo csv desde url: // csvURL: 'https://demo-live-data.highcharts.com/vs-load.csv', // enablePolling: true, // dataRefreshRate: 5, // >>> Desde una tabla html definida (solo usar su id en <table id="idHtmlDatatable">) // table:"idHtmlDatatable" // >>> Definicion por columnas: /* columns: [ [null, 'Apples', 'Pears', 'Oranges'], // categories ['Ola', 1, 4, 3], // first series ['Kari', 5, 4, 2] // second series ] */ }, legend:{ accessibility:{ enabled:true, }, sonification:{ }, enabled:true, alignColumns:true, verticalAlign:"bottom", align:"left", layout:"horizontal", // horizontal = leyenda debajo | vertical = leyenda izq-der (depende de align) itemDistance:20, itemHiddenStyle:{color:"#ccc"}, itemWidth:0, backgroundColor:"", borderColor: "#f1f1f1", borderWidth: 0, reversed:false, // invertir los items de orden labelFormatter:function(){ return this.name }, symbolHeight:10, symbolWidth:10, symbolRadius:0, labelFormat:"{name}", labelFormatter:undefined, useHTML:true }, exporting:{ enabled:false, }, /* plotOptions:{ }, */ tooltip:{ enabled:true, useHTML:true, animation:true, crosshairs:false, // agrega una banda vertical sobre el punto donde se posiciona el cursor backgroundColor:"#FFFFFF", borderColor:"#DADADA", displayErrors:true, borderWidth:1, borderRadius:0, followPointer:false, hideDelay:200, outside:true, // renderizar tooltip fuera del svg o dentro shadow:false, shared:false, // si es true se necesita modificar formatter callback o desactivarlo (una etiqueta que agrupa las series) split:false, // si es true se necesita modificar formatter callback o desactivarlo (separa en etiquetas separadas por serie) stickOnContact:false, // Si es true el tt se mostrara cuando se pase el cursor por el punto o marcador de la serie nullFormatter: function(p){ return "Es un valor null" }, formatter:undefined }, /* responsive:{ rules:[ { chartOptions:{}, conditions:{ callback:undefined, maxHeight:undefined, maxWidth:undefined, minHeight:0, minWidth:0 } } ] }, */ xAxis: { alignTicks:true, // alineacion de ticks cuando hay multiples axes accessibility:{}, categories: ['<strong>Aguascalientes</trong>','Durango','Nuevo Leon','Chiapas','San Luis','Zacatecas','Baja California Sur','Oaxaca','Quintana Roo'], crosshair:{ color:"#cccccc", dashStyle:"dot", snap:true, width:1 }, events:{}, gridLineColor:"#f1f1f1", gridLineDashStyle:"Solid", gridLineInterpolation:undefined, gridLineWidth:1, lineColor:"#d7d7d7", lineWidth:1, labels:{ align:undefined, allowOverlap:true, autoRotation:[-80], enabled:true, rotation:undefined, // si rotation tiene valores, autorotation se ignora reserveSpace:true, step:0, // cada cuantos mostrara la categoria style:{ color:"#525252", fontSize:"0.8em" }, useHTML:true, // formatter:function(){} }, // Plot & bands: coloreado de zonas especificas segun el rango especificado /* plotBands:[{ color:"#FCFFC5", from:2, to:4, }], */ // Plot & bands: Linea para indicar una zona dentro del plot segun el value especificado /* plotLines:[{ color:"#FF0000", dashStyle:"Solid", zIndex:5, width:2, value:5, label:{ text:"Etiqueta plotline", align:"left", textAlign:"left", rotation:0, style:{ color:"#FF0000", fontWeigth:"bold" } } }], */ reversed:false, // invierte el orden de las categorias tickWidth:1, tickLength:8, tickColor:"#d7d7d7", tickPosition:"outside", tickmarkPlacement:"on", // on = centrado en la etiqueta | between = entre las etiquetas title:{ align:"high", // low = left | middle = center | high = right enabled:true, margin:20, style:{ color:"#666666", fontSize:"0.8em" }, useHTML:true, text:"", }, visible:true, // oculta / muestra el eje X }, yAxis:{ accessibility:{}, crosshair:{ color:"#cccccc", dashStyle:"dot", snap:true, width:1 }, gridLineColor:"#f1f1f1", gridLineDashStyle:"Solid", gridLineInterpolation:undefined, gridLineWidth:1, lineColor:"#d7d7d7", lineWidth:1, labels:{ align:undefined, allowOverlap:true, autoRotation:[-80], enabled:true, rotation:undefined, // si rotation tiene valores, autorotation se ignora reserveSpace:true, step:0, // cada cuantos mostrara la categoria style:{ color:"#525252", fontSize:"0.8em" }, useHTML:true, // formatter:function(){} }, max:undefined, // Maximo valor especificado del eje Y, undefined = lo toma de los datos de entrada minTickInterval:1, //Intervalo de saltos en los valores del eje Y opposite:false, // Plot & bands: coloreado de zonas especificas segun el rango especificado /* plotBands:[{ color:"#ffe8a3", from:0, to:2, }], */ // Plot & bands: Linea para indicar una zona dentro del plot segun el value especificado /* plotLines:[{ color:"#d8a408", dashStyle:"Solid", zIndex:5, width:2, value:4, label:{ text:"Etiqueta plotline", align:"left", textAlign:"left", rotation:0, style:{ color:"#d8a408", fontWeigth:"bold" } } }], */ reversed:false, stackLabels:{}, // para graficas stack startOnTick:true, // comienda desde el punto del eje X ( punto 0) tickWidth:1, tickLength:8, tickColor:"#d7d7d7", tickPosition:"outside", tickmarkPlacement:"on", // on = centrado en la etiqueta | between = entre las etiquetas title:{ align:"high", // low = left | middle = center | high = right enabled:true, margin:20, style:{ color:"#666666", fontSize:"0.8em" }, useHTML:true, text:"", }, visible:true, // mostrar / ocultar el eje Y }, plotOptions:{ }, series: [{ name:"2023", data:[ {indicador:"Población total", area:"Aguascalientes", periodo:2022,value:10, y:10}, {indicador:"Población total", area:"Durango", periodo:2022,value:20, y:20}, {indicador:"Población total", area:"Nuevo Leon", periodo:2022,value:30, y:30}, {indicador:"Población total", area:"Chiapas", periodo:2022,value:40, y:40}, {indicador:"Población total", area:"San Luis", periodo:2022,value:null, y:null}, {indicador:"Población total", area:"Zacatecas", periodo:2022,value:20, y:20}, {indicador:"Población total", area:"Baja California", periodo:2022,value:70, y:70}, {indicador:"Población total", area:"Oaxaca", periodo:2022,value:50, y:50}, {indicador:"Población total", area:"Quintana Roo", periodo:2022,value:90, y:90}, ] }] } let ParametrosUsuario = { id:"", // _chartRef:null, // guarda la referencia del obj DOM donde se genera el svg de highcharts // _chartOptions:{}, // objeto de configuracion para generar la gráfica de Highcharts exe:true, tipo:"linea", titulo:"", alto:400, mostrar:true, herramientas:{ id:"", mostrar:true, exportarCsv:true, exportarXls:true }, color:"Tema.Azul", margen_derecho:10, margen_izquierdo:10, margen_superior:10, margen_inferior:10, // alto:400, grid:{ x:true, y:true }, ejeY:{ mostrar:true, texto:"", posicion:"l", }, ejeX:{ mostrar:true, texto:"", posicion:"b" }, leyenda: { mostrar:true, columnas:true, ancho_item:100, posicion:"", // valores posibles: inferior, superior, izquierda, derecha [default = inferior] }, series:{ mostrar:true, // curva:true, // puntos:true, // linea_guia_x:true, // linea_guia_y:true, // punto_guia:true, // etiquetas:{ //} }, tooltip:{ mostrar:true, // seguir_puntero:false, // seguimiento del cursor // formato:function(){} } } const generaJsonGrafica = (parametros, dataset) => { let {offsetWidth} = parametros.refContainer.current; // referencia del contenedor <section> del gráfico /* console.group("## Parametros del usuario") console.log(parametros) console.groupEnd() */ // Objeto que concentra todas las opciones con valores finales let CHART = {}; // Segmentos del objeto de opciones: Permite modificarlos y asignar los valores introducidos por el usuario let { chart, colors, data, exporting, legend, plotOptions, tooltip, xAxis, yAxis, series, responsive } = OpcionesGrafica; // Se valida que el tipo de grafica solicitado por el usuario exista en el proyecto. // de lo contrario regresa el objeto vacio y mensaje de error const tipoGrafica = Helper.buscaTipoGrafica(parametros.tipo) // console.log("tipoGrafica: ",tipoGrafica) if(tipoGrafica !== null && tipoGrafica !== undefined){ /** ########## CONFIGURACION DEL BJETO CHART */ chart.type = tipoGrafica.nombre; chart.height = parametros.alto; if(parametros.animaciones){ chart.animation = parametros.animaciones } CHART.chart = chart; /** ########## CONFIGURACION LEGEND */ const parametrosLeyenda = parametros.leyenda; if(parametrosLeyenda !== undefined){ /* console.group("## parametros leyenda:") console.log(parametrosLeyenda) console.groupEnd() */ // Mostrar u ocultar la layenda if(parametrosLeyenda.mostrar !== undefined && typeof parametrosLeyenda.mostrar === "boolean"){ legend.enabled = parametrosLeyenda.mostrar; } // Mostrar en columnas on inline if(parametrosLeyenda.columnas !== undefined && typeof parametrosLeyenda.columnas === "boolean"){ legend.alignColumns = parametrosLeyenda.columnas; } // Define el ancho de cada item siempre y cuando la propiedad sea columnas = true y ancho_item > 0 if(legend.alignColumns === true && parametrosLeyenda.ancho_item !== undefined && typeof parametrosLeyenda.ancho_item === "number"){ legend.itemWidth = parametrosLeyenda.ancho_item; } // Posicion de la leyenda if(parametrosLeyenda.posicion !== undefined && typeof parametrosLeyenda.posicion === "string"){ const getPosicion = (param) => { var posiciones = { 'superior': () => {return {verticalAlign:"top", layout:"horizontal"};}, 'inferior': () => {return {verticalAlign:'bottom', layout:'horizontal'};}, 'izquierda': () => {return {verticalAlign:'top', layout:'vertical'};}, 'derecha': () => {return {align:'right', verticalAlign:'top', layout:'vertical'};}, 'default': () => { return {verticalAlign:'bottom', layout:'horizontal'}; } }; return (posiciones[param] || posiciones['default'])(); } let l; const pos = getPosicion(parametrosLeyenda.posicion); legend.align = pos.align || legend.align; legend.verticalAlign = pos.verticalAlign; legend.layout = pos.layout; } // Formato de los items de la leyenda (por defecto) legend.labelFormat = undefined; legend.labelFormatter = function(e){ const {name} = this; return `<div title="${name}">${name}</div>`; } CHART.legend = legend; } /** ########## CONFIGURACION TOOLTIP */ if(parametros.tooltip !== undefined){ const parametrosTooltip = parametros.tooltip; console.group("## parametros tooltip:") console.log(parametrosTooltip) console.groupEnd() // Mostrar u oculta el tooltip if(parametrosTooltip.mostrar !== undefined && typeof parametrosTooltip.mostrar === "boolean"){ tooltip.enabled = parametrosTooltip.mostrar; } // Modo de visualizacion del tooltip let modoTip = {}; if(parametrosTooltip.modo === undefined){ modoTip = Helper.buscaTooltip(""); } else { modoTip = Helper.buscaTooltip(parametrosTooltip.modo); } // Modo tooltip: por defecto normal if(modoTip.alias === "normal"){ tooltip.shared = false; tooltip.split = false; tooltip.formatter = function(p){ const point = this.point; // const options = point.options; const series = this.series; // const cat = this.key; const color = this.color; const template = ` <div class="sdg-tooltip" style="width:${Math.ceil(offsetWidth/3)+'px'}"> <div><strong>${series.name}</strong></div> <div> <i class="sdg-tooltip-color" style="background-color:${color};"></i> <span><strong>${point.category}</strong></span> <span>${point.y}</span> </div> </div> `; return template; } // Modo tooltip: compartido / shared } else if(modoTip.alias === "compartido"){ tooltip.shared = true; // Modo tooltip: dividido / split } else if(modoTip.alias === "dividido"){ tooltip.split = true; tooltip.formatter = function(){ const points = this.points; return [`<strong class="sdg-tooltip">${this.x}</strong>`].concat( points? points.map((p) => { return ` <div class="sdg-tooltip" style="width:${Math.ceil(offsetWidth/3)+'px'}"> <i class="sdg-tooltip-color" style="background-color:${p.color};"></i> <span><strong>${p.series.name}</strong></span> <span>${p.y}</span> </div> `; }) : [] ) /* return [""].concat( points? points.map((p) => { return ` <div><strong>${p.series.name}</strong></div> <div> <i style="background-color:${p.color};width:10px;height:10px;display:inline-block;padding:0 4px 0 0"></i> <span><strong>${p.point.category}</strong></span> <span>${p.y}</span> </div> `; }) : [] ) */ }; } CHART.tooltip = tooltip; } /** ########## CONFIGURACION SERIES */ // console.log(dataset); xAxis.categories = dataset.categorias.map((c) => c.nombre); let aSeries = []; aSeries = dataset.datos.map((s) => { let oData = {}; let serie_data = s.data.map((d) => { let nVal = Helper.stringANumero(d.valor) d.valor = nVal d.y = nVal; return d; }) oData.data = serie_data oData.name = s.grupo; return oData; }) CHART = OpcionesGrafica; CHART.xAxis.categories = xAxis.categories; CHART.series = aSeries; // console.log(CHART) } // if(GRAFICAS.tipos[paramUsuario.tipo]) // Primero configurar todos los parametros generales // chart, colors, legend, tooltip, exporting, plotOptions // Segundo configurar los ejex // xAxis, yAxis // Tercero configurar los ajustes de responsivo // responsive // Cuarto configura los datos // series // Quinto asignar todas las propiedades en un objeto y retornarlo // CHART console.log(CHART) return CHART; } export { OpcionesHighcharts, OpcionesGrafica, ParametrosUsuario, generaJsonGrafica }