Bonne façon de dessiner le quadrillage

OK, je commence à me familiariser avec D3 mais je suis encore un peu flou sur certaines choses. J'essaie maintenant de tracer des lignes de grille mais je me rends compte que je peux pirater plutôt que de le faire correctement. J'ai essayé d'ajouter quelques gridlines, en utilisant un tutoriel, mais j'ai fini avec beaucoup de code que je semble être Jimmy rigging afin de le faire s'aligner correctement. Je me demandais si quelqu'un pouvait m'indiquer une meilleure façon d'écrire ça...

le code original est celui-ci.

        <script type="text/javascript">

            //Width and height
            var w = 800;
            var h = 400;
            var padding = 20;
            var border=1;
            var bordercolor='black';


            var dataset = [
                            [5, 20], [480, 90], [250, 50], [100, 33], [330, 95],[-50,-100],[50,-45],
                            [410, 12], [475, 44], [25, 67], [85, 21], [220, 88],[-480, -467], [3,-90],[468,481]
                          ];

                // create scale functions
                var xScale = d3.scale.linear()
                                 .domain([d3.min(dataset, function(d) { return d[0]; }), d3.max(dataset, function(d) { return d[0]; })])
                                 .range([padding, w - padding * 2]);

            var yScale = d3.scale.linear()
                                 .domain([d3.min(dataset, function(d) { return d[0]; }), d3.max(dataset, function(d) { return d[1]; })])
                                 .range([h - padding, padding]);

                var rScale = d3.scale.linear()
                .domain(  [-100,      d3.max(dataset, function(d) { return d[1];            })]   )
                .range([2,5]);

            //Create SVG element
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h)
                        .attr("border",border)
                        ;

            //define X axis   this is rly a function, remember, variables can hold functions in JS
                var xAxis = d3.svg.axis()
                        .scale(xScale)
                        .orient("bottom")
                        .ticks(1)
                        .tickSize(-h, 0, 0)
                        ;   //Set rough # of ticks


            //Define Y axis
                var yAxis = d3.svg.axis()
                        .scale(yScale)
                        .orient("left")
                        .ticks(1)
                        .tickSize(-w, 0, 0)
                        ;




                //create the circles
            svg.selectAll("circle")
               .data(dataset)
               .enter()
               .append("circle")
               .attr("cx", function(d) {
                    return xScale(d[0]);
               })
               .attr("cy", function(d) {
                    return yScale(d[1]);
               })
               .attr("r", 3);





  //   draw axes here
   svg.append("g")
    .attr("class", "axis") //assign "axis" class
    .attr("transform", "translate(0," + (h - padding) +")")
    .call(xAxis);



       svg.append("g")
    .attr("class", "axis") //assign "axis" class
    .attr("transform", "translate(" + padding + ",0)"       )
    .call(yAxis);
// end draw axes here
        </script>

et le code que j'ai ajouté dans la deuxième lien est ici

var vis = svg.append("svg:g")
    .attr("transform", "translate(20,0)")


var rules = vis.append("svg:g").classed("rules", true)


rules.append("svg:g").classed("grid x_grid", true)
    .attr("transform", "translate(-20,"+h+")")
    .call(d3.svg.axis()
      .scale(xScale)
      .orient("bottom")
      .ticks(4)
      .tickSize(-h,0,0)
      .tickFormat("")
    )

rules.append("svg:g").classed("grid y_grid", true)
    .call(d3.svg.axis()
      .scale(yScale)
      .orient("left")
      .ticks(5)
      .tickSize(-w,0,0)
      .tickFormat("")
    )

rules.append("svg:g").classed("labels x_labels", true)
    .attr("transform", "translate(-20,"+ h +")")
    .call(d3.svg.axis()
      .scale(xScale)
      .orient("bottom")
      .ticks(4)
      .tickSize(0)
            .tickFormat("")
      // .tickFormat(d3.time.format("%Y/%m"))
    )

rules.append("svg:g").classed("labels y_labels", true)
    .call(d3.svg.axis()
      .scale(yScale)
      .orient("left")
      .ticks(5)
      .tickSubdivide(1)
      .tickSize(0, 0, 0)
            .tickFormat("")
    )

Encore une fois, vraiment reconnaissant de toute aide

37
demandé sur Seanny123 2013-03-23 01:40:22

6 réponses

en Supposant que vous avez Mike Bostock est standard marges défini et vous avez défini une échelle linéaire pour l'axe des y le code suivant créera des lignes horizontales sans utiliser tickSize().

svg.selectAll("line.horizontalGrid").data(yScale.ticks(4)).enter()
    .append("line")
        .attr(
        {
            "class":"horizontalGrid",
            "x1" : margin.right,
            "x2" : width,
            "y1" : function(d){ return yScale(d);},
            "y2" : function(d){ return yScale(d);},
            "fill" : "none",
            "shape-rendering" : "crispEdges",
            "stroke" : "black",
            "stroke-width" : "1px"
        });
66
répondu arete 2017-05-23 10:31:16

je suggère d'utiliser d3.svg.axe.)(scale () pour lier la grille à vos coordonnées. J'ai dessiné un exemple basé sur votre code:http://jsfiddle.net/temirov/Rt65L/1/

Grid example

L'essentiel est d'utiliser les échelles existantes, x et y, et à utiliser les tiques comme une grille. Comme yAxis et xAxis sont déjà définis, nous pouvons les réutiliser. Voici le code correspondant:

//Draw a grid
var numberOfTicks = 6;

var yAxisGrid = yAxis.ticks(numberOfTicks)
    .tickSize(w, 0)
    .tickFormat("")
    .orient("right");

var xAxisGrid = xAxis.ticks(numberOfTicks)
    .tickSize(-h, 0)
    .tickFormat("")
    .orient("top");

svg.append("g")
    .classed('y', true)
    .classed('grid', true)
    .call(yAxisGrid);

svg.append("g")
    .classed('x', true)
    .classed('grid', true)
    .call(xAxisGrid);
16
répondu Vadym Tyemirov 2014-03-26 04:33:52

vous pourriez utiliser le ticks() fonction de votre échelle pour obtenir les valeurs de TIC et puis les utiliser dans un appel de données pour dessiner les lignes.

var ticks = xScale.ticks(4);
rules.selectAll("path.xgrid").data(ticks).enter()
     .append("path")
     .attr("d", function(d) {
       return "M" + xScale(d) + " " + padding + "L" + xScale(d) + " " + (h-padding);
     });

vous pouvez préférer utiliser un générateur de ligne pour les lignes de grille au lieu de créer le chemin manuellement. Cela fonctionne de la même façon pour les lignes de la grille y, seulement que la coordonnée y est constante et varie de 0 à la largeur du graphique. Vous devrez peut-être ajuster les valeurs début et fin pour faire "joli".

11
répondu Lars Kotthoff 2013-03-22 21:54:07
function createsGrid(data) {
       var grid = gridLine.selectAll("line.horizontalGrid").data(scaleY.ticks());

       grid.enter()
       .append("line")
       .attr("class","horizontalGrid");

       grid.exit().remove();

       grid.attr({
               "x1":0,
               "x2": width,
               "y1": function (d) { return scaleY(d); },
               "y2": function (d) { return scaleY(d); }
                });
}

et définissez ce qui suit dans votre fichier CSS

line.horizonalGrid{
  fill : none;
 shape-rendering : crispEdges;
 stroke : black;
 stroke-width : 1.5px;
} 
1
répondu mfroese 2014-07-23 22:59:31

dans le projet d3fc nous avons créé un quadrillage composant qui rend exactement de la même manière que L'axe D3(v4).

Voici un exemple d'utilisation:

var width = 500, height = 250;
var container = d3.select("#gridlines")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

var xScale = d3.scaleLinear()
  .range([0, 100]);

var yScale = d3.scaleLinear()
  .range([0, 100]);

var gridline = fc.annotationSvgGridline()
  .xScale(xScale)
  .yScale(yScale);

container.append("g")
  .call(gridline);

qui rend comme suit:

enter image description here

l'espacement des lignes est déterminé par les tiques fournies par les axes associés.

Divulgation: je suis un collaborateur principal à l'd3fc projet!

1
répondu ColinE 2016-12-27 08:27:32

Vous pouvez simplement utiliser innerTickSize, au lieu de tickSize:

            var xAxis = d3.svg.axis()
                    .scale(xScale)
                    .orient("bottom")
                    .ticks(1)
                    .innerTickSize(-h);
0
répondu Neptunemo 2015-11-12 03:10:58