10
votes

Contrôle de la graphique Y Axe Auto-Échelle automatique sur le défilement

Je cherche le net depuis un certain temps, mais je n'ai toujours trouvé aucune bonne solution à mon problème. Je souhaite faire du graphique MS pour réaffecter automatiquement l'axe Y sur le défilement pour vous assurer que tous les points de données sont visibles. La torsion est que je dois avoir la possibilité d'exclure certaines séries d'être utilisées pour l'échelle automatique. Jusqu'à présent, je n'ai trouvé que des solutions qui offrent une itérale à travers la collection entière de l'événement AxisviewChanged, ce qui ne fonctionne pas bien lorsque vous avez de grandes collections de points et quelques séries à parcourir. Je me demandais s'il y avait un moyen de réduire la recherche en obtenant des points de données entre les valeurs MIN et MAX x actuellement visibles. Toute aide serait appréciée.

Modifier Heres l'image. Comme vous pouvez le voir, les chandeliers au milieu ne sont pas entièrement visibles. Entrez la description de l'image ici


2 commentaires

MMH n'est pas clair pour moi ... vous voulez réduisant l'axe Y tout en faisant défiler l'axe X, non? Sinon, cela n'a aucun sens pour moi. BTW pourriez-vous donner un exemple visuel de ce dont vous avez besoin?


@Digemall Oui, c'est correct


5 Réponses :


6
votes

Vous pouvez essayer ce code xxx

Entrez la description de l'image ici < / p>


7 commentaires

@Stecya. J'ai DateTime comme valeur X qui rend la valeur maximale de la valeur inférieure à la valeur minimale, les points éteignent donc une collection vide.


Vous pouvez utiliser graph1.series [0] .isxvalueindexed = true; alors la valeur x sera entier et les locales sont toujours datétières


@Stecya. Mais cela éliminerait toutes les lacunes vides de l'axe X, n'est-ce pas?


Oui, mais comme je le vois par écran, vous développez des cartes financières, et il n'y a pas de données samedi / dimanche, donc il y aurait un grand espace vide


@Stecya. Hmm, pour moi Axisx.Minimum retourne toujours 1 et Axisx.Maximum renvoie toujours le nombre de points, de sorte que cela finit par chercher dans l'ensemble de la collection, mais je pense que je pourrais obtenir la position de la barre de défilement.


Oh je vois, j'ai enlevé cette barre de défilement laide et mis en œuvre bouger et traîner moi-même


@Stecyai j'ai été temporairement réaffecté à une tâche différente, une fois que j'en ai fini, je reviendrai sur cette question et j'écris à mes progrès.



5
votes

Utilisez une requête pour savoir quelle série que vous souhaitez utiliser pour rechercher Ymin et Ymax dans le code.

private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
    {
        if (e.Axis.AxisName == AxisName.X)
        {
            int start = (int)e.Axis.ScaleView.ViewMinimum;
            int end = (int)e.Axis.ScaleView.ViewMaximum;

            // Series ss = chart1.Series.FindByName("SeriesName");
            // use ss instead of chart1.Series[0]

            double[] temp = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToArray();
            double ymin = temp.Min();
            double ymax = temp.Max();

            chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin;
            chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin;
        }
    }


0 commentaires

3
votes

Il s'agit d'une amélioration mineure de l'excellente soumission de Shivaram KR, afin d'empêcher l'ouverture, la fermeture arrière et la faible dépression du bas des points les plus bas sur les graphiques financières avec quatre valeurs de Y: haut, faible et ouvert.

// The following line goes in your form constructor
this.chart1.AxisViewChanged += new EventHandler<ViewEventArgs> (this.chart1_AxisViewChanged);


private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
{ 
    if (e.Axis.AxisName == AxisName.X) 
    { 
        int start = (int)e.Axis.ScaleView.ViewMinimum; 
        int end = (int)e.Axis.ScaleView.ViewMaximum; 
        // Use two separate arrays, one for highs (same as temp was in Shavram's original)
        // and a new one for lows which is used to set the Y axis min.
        double[] tempHighs = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToArray();
        double[] tempLows = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[1]).ToArray();
        double ymin = tempLows.Min();
        double ymax = tempHighs.Max();

        chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin; 
        chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin; 
    } 
} 


0 commentaires

0
votes

Basé sur les réponses précédentes

private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
    {
        if(e.Axis.AxisName == AxisName.X)
        {
            int start = (int)e.Axis.ScaleView.ViewMinimum;
            int end = (int)e.Axis.ScaleView.ViewMaximum;

            List<double> allNumbers = new List<double>();

            foreach(Series item in chart1.Series)
                allNumbers.AddRange(item.Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToList());

            double ymin = allNumbers.Min();
            double ymax = allNumbers.Max();

            chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin;
            chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin;
        }
    }


0 commentaires

0
votes

Les réponses ci-dessus ont été très utiles pour moi. Cependant, j'ai un tableau avec plusieurs zones de cartographie. J'ai adapté le code à l'échelle à toutes les zones de graphique: xxx


0 commentaires