javascript tipos - ¿Cómo crear un gráfico de rango de columnas en Highcharts utilizando las funciones de rango y navegador?





con para (2)


Entonces, después de unas pocas horas de excavación, acabo de descubrir al culpable (o realmente lo espero). El problema es su definición de formateador de etiquetas y yAxis :

yAxis: {
  tickInterval: 1,
    gridLineWidth: 1,
    labels: {
    formatter: function() { // THIS IS THE PROBLEM
      if (tasks[this.value]) {
        return tasks[this.value].name;
      }
    }
  },
  startOnTick: false,
    endOnTick: false,
    title: {
    text: 'Task'
  }
},

En realidad, no verifica si debe mostrar la etiqueta de acuerdo con task.intervals (consulte json.js ). Una simple actualización ( Plunker ) del formateador parece funcionar:

  yAxis: {
    tickInterval: 1,
    gridLineWidth: 1,
    labels: {
      formatter: function () {
        console.log("scripts.js - yAxis.labels.formatter", this.value);
        if (tasks[this.value]) {

          //if (tasks[this.value].name === 'LILLY_C') {
            var _xAxis = this.chart.axes[0];
            var _task = tasks[this.value];
            var _show = false;

            // Not optimized for large collections
            for (var _i = 0; _i < _task.intervals.length; _i++) {
              var _int = _task.intervals[_i];
              if (_xAxis.min <= _int.to) {
                _show = true;
              }
            }

            console.log("scripts.js - yAxis.labels.formatter",
              tasks[this.value].name,
              _show,
              _xAxis.min,
              _xAxis.max,
              _task.intervals
            );

            if (_show) {
              return tasks[this.value].name;
            } else {
              return;
            }
          //}

          //return tasks[this.value].name;
        }
      }
    },
    startOnTick: false,
    endOnTick: false,
    title: {
      text: 'Task'
    }
  },

Ver Plunker para la Plunker .

El significado de las etiquetas yAxis es: Mostrar etiqueta si ve una ejecución en el gráfico o si hay una ejecución a la derecha del gráfico. Por favor modifique la condición

if (_xAxis.min <= _int.to) {

como veas conveniente.

Descargo de responsabilidad: No uso Highcharts, por lo que esta respuesta intenta explicar el problema y no sugerir un Highcharts-forma de resolver el problema.

Lecciones aprendidas:

  • yaxis-plugin.js es irrelevante para el problema.
  • Highstock.js es una biblioteca de código abierto ( highstock.src.js ). Cualquier depuración es mucho más fácil si depura el código fuente original. El código reducido agrega complejidad y conjeturas innecesarias. He descargado la biblioteca y agregado un poco de console.log() para descubrir qué está pasando.

Tengo un requisito para trazar el historial de ejecución de una tarea en Highcharts. Debe mostrar que ejecuta el historial de las tareas como una barra horizontal. Hay requisitos adicionales que agregué como actualización a continuación. Recientemente descubrí que la opción inverted no es compatible con StockChart y que solo el navigator y rangeSelector están disponibles en StockChart. Por lo tanto, estoy usando esas funciones.

Entonces, para lograr el requisito, creé algo similar a este ejemplo jsfiddle (encontrado en algún lugar mientras navegaba, no recuerdo la fuente) y terminé con este enlace plunker con la ayuda de mi question anterior, gracias a Pawel Fus.

Actualización de la pregunta para evitar confusiones

Requerimientos adicionales:

Mostrar solo aquellas tareas que se ejecutaron en un rango de fecha y hora en particular. En caso de que haya demasiadas ejecuciones, como más de 10 ejecuciones, entonces debe haber una manera de mostrar solo 10 tareas visiblemente con un eje y que se pueda desplazar para mostrar otras tareas. enlace de plunker al problema

Explicación del problema del plunker anterior.

Si marca la captura de pantalla siguiente desde arriba, el intervalo de tiempo va del 12/12/2014 09:32:26 al 12/12/2014 10:32:26 y solo hay 2 tareas que se han ejecutado m_ARRAYV_SALES_ZIG1_CALL2_VOD__C_OB & m_ZIG2_HCP_MERGE_IB_CN . Sin embargo, puedo ver otra tarea entre LILLY_C que ni siquiera se ejecutó en este rango de fechas. (En datos reales hay más de 10 tareas que saturan este gráfico que ni siquiera está dentro de este rango de tiempo)

Además, si observa que en la esquina inferior derecha, el tiempo cambió de 09:38 a 19:20 . 19:20 es la hora de m_ZIG2_HCP_MERGE_IB_CN tarea m_ZIG2_HCP_MERGE_IB_CN . A continuación están mis opciones de gráfico

    var chart_options = {
            chart: {
                renderTo: 'container',
                height: 600
            },
            title: {
            },
            credits: {
                enabled: false
            },
            xAxis: {
                type: 'datetime',
                gridLineWidth: 1,
                tickInterval: 1 * 3600 * 1000,
                dateTimeLabelFormats: {
                    month: '%b %e, %Y'
                }
            },
            yAxis: {                    
                tickInterval: 1,
                gridLineWidth: 1,
                labels: {
                    formatter: function() {
                        if (tasks[this.value]) {
                            return tasks[this.value].name;
                        }
                    }
                },
                startOnTick: false,
                endOnTick: false,
                title: {
                    text: 'Task'
                }
            },
            rangeSelector: {
                selected: 0,
                buttons: [ {
                    type: "minute",
                    count: 60,
                    text: "1h"
                }, {
                    type: "minute",
                    count: 180,
                    text: "3h"
                }, {
                    type: "minute",
                    count: 300,
                    text: "5h"
                }],
                inputDateFormat: '%m/%d/%Y %H:%M:%S',
                inputEditDateFormat: '%m/%d/%Y %H:%M:%S',
                inputBoxWidth: 120
            },
            navigator: {
                enabled: false
            },
            legend: {
                enabled: false
            },
            tooltip: {
                shared: false,
                formatter: function() {
                    var str = '';
                    str += 'Task: ' + this.series.name + '<br>';
                    str += 'From: ' + Highcharts.dateFormat('%m/%d/%y %H:%M', this.point.from) + '<br>';
                    str += 'To: ' + Highcharts.dateFormat('%m/%d/%y %H:%M', this.point.to) + '<br>';
                    return str;
                }
            },
            plotOptions: {
                line: {
                    lineWidth: 10,
                    marker: {
                        enabled: true
                    },
                    dataLabels: {
                        enabled: true,
                        align: 'left',
                        formatter: function() {
                            return this.point.options && this.point.options.label;
                        }
                    },
                    states:{
                        hover:{
                            lineWidth:10
                        }
                    }
                },
                series: {
                    cursor: 'pointer',
                    point: {
                        events: {
                            click: function () {
                                var query = '{ "task_id": "'+this.task_id+'","start_time": '+this.from+',"exclude_interval": '+opExcludeMinutes+',"size": 10 }';
                                $scope.taskName = this.series.name;
                                $scope.isTaskSelected = false;
                                $scope.operationalReportAgentTaskHistoryServiceRequest(query);
                            }
                        }
                    }
                }
            },
            series: seriesData
        };



Esta respuesta es para proporcionar suficiente información para no cambiar / mutar el estado directamente en Reaccionar.

React sigue el flujo de datos unidireccional . Lo que significa que el flujo de datos dentro de reaccionar debe y se espera que esté en una ruta circular.

Flujo de datos de React sin flujo

Para hacer que React funcione así, los desarrolladores hicieron que el React fuera similar a la programación funcional . La regla del pulgar de la programación funcional es la inmutabilidad . Déjame explicarte alto y claro.

¿Cómo funciona el flujo unidireccional?

  • states son un almacén de datos que contiene los datos de un componente.
  • La view de un componente se representa en función del estado.
  • Cuando la view necesita cambiar algo en la pantalla, ese valor debe ser suministrado desde la store .
  • Para que esto suceda, React proporciona la función setState() que toma un object de nuevos states y hace una comparación y fusión (similar a object.assign() ) sobre el estado anterior y agrega el nuevo estado al almacén de datos de estado.
  • Siempre que los datos en la tienda de estado cambien, reaccionar activará una nueva representación con el nuevo estado que la view consume y lo mostrará en la pantalla.

Este ciclo continuará a lo largo de la vida del componente.

Si ve los pasos anteriores, muestra claramente que suceden muchas cosas cuando cambia el estado. Por lo tanto, cuando mute el estado directamente y llame a setState() con un objeto vacío. El previous state se verá contaminado con tu mutación. Debido a lo cual, la comparación y fusión superficial de dos estados se verá alterada o no sucederá, porque ahora solo tendrá un estado. Esto interrumpirá todos los métodos del ciclo de vida de React.

Como resultado, su aplicación se comportará de forma anormal o incluso se bloqueará. La mayoría de las veces, no afectará su aplicación porque todas las aplicaciones que utilizamos para probar esto son muy pequeñas.

Y otra desventaja de la mutación de Objects y Arrays en JavaScript es que cuando asigna un objeto o una matriz, solo está haciendo una referencia de ese objeto o esa matriz. Cuando los mutes, toda la referencia a ese objeto o esa matriz se verá afectada. Reacciona maneja esto de una manera inteligente en segundo plano y simplemente nos da una API para que funcione.

Errores más comunes que se cometen cuando se manejan estados en reacción

//original state
this.state = {
   a: [1,2,3,4,5]
}

//changing the state in react
//need to add '6' in the array

//bad approach
const b = this.state.a.push(6)
this.setState({
  a: b
}) 

En el ejemplo anterior, this.state.a.push(6) el estado directamente. Asignarlo a otra variable y llamar a setState es el mismo que se muestra a continuación. Como mutamos el estado de todos modos, no tiene sentido asignarlo a otra variable y llamar a setState con esa variable.

 //same as 
 this.state.a.push(6)
 this.setState({})

La mayoría de la gente hace esto. Esto está muy mal . Esto rompe la belleza de React y te convertirá en un mal programador.

Entonces, ¿cuál es la mejor manera de manejar estados en reaccionar? Dejame explicar.

Cuando necesite cambiar 'algo' en el estado existente, primero obtenga una copia de ese 'algo' del estado actual.

//original state
    this.state = {
       a: [1,2,3,4,5]
    }

 //changing the state in react
 //need to add '6' in the array

 //create a copy of this.state.a
 //you can use ES6's destructuring or loadash's _.clone()
 const currentStateCopy = [...this.state.a]

Ahora, la mutación de currentStateCopy no currentStateCopy el estado original. Realice operaciones sobre currentStateCopy y currentStateCopy como el nuevo estado usando setState()

currentStateCopy.push(6)
this.state({
 a: currentStateCopy
})

Esto es embellecer ¿verdad?

Al hacer esto, todas las referencias de this.state.a no se verán afectadas hasta que usemos setState . Esto le permite controlar su código y esto lo ayudará a redactar una prueba elegante y a confiar en el rendimiento del código en producción.

Para responder tu pregunta,

¿Por qué no puedo modificar directamente el estado de un componente?

Sí, puedes . Pero, debes enfrentar las siguientes consecuencias.

  1. Cuando escalas, estarás escribiendo un código inmanejable.
  2. Perderá el control de state todos los componentes.
  3. En lugar de usar React, escribirás códigos personalizados sobre React.

La inmutabilidad no es algo necesario porque Javascript tiene un solo hilo. Pero, es bueno seguir una práctica que te ayudará en el largo plazo.

PD. He escrito alrededor de 10000 líneas de código jct Reac mutable. Si se rompe ahora, no sé dónde mirar porque todos los valores están mutados en alguna parte. Cuando me di cuenta de esto, comencé a escribir código inmutable. ¡Créeme! Eso es lo mejor que puedes hacer con un producto o una aplicación.

¡Espero que esto ayude!







javascript angularjs highcharts highstock