简体   繁体   中英

Draw a table with d3 and typeScript

i think d3 makes a really simple work really complicated.

i am looking to make a monthly table with d3 and typeScript.

i have found a solution where i can see 10 days but that is not a dynamic calender, that is hard coded.

i have looked a lot and all i found is this one ..

[jsfiddle][1]

How can i make this a monthly calender where all the days will be in one row ..

Any one knows any solution to this problem !

The reason why I want to using d3 because I need data inside of that table, which will be always integer .

So data type - `integer

Data Source - CSV

Problem With D3 - How can i make a calendar with all days in one row

Ok, so I finally found some time.

I must admit, it was only after rereading the question, that i realized you need an answer in typescript. I don't know typescript, but I am going to give an answer anyway, since I guess the main problem is D3, especially then the csv part. If I am wrong, I can delete this answer, but I figured that one answer that is close to what you want, is better then no answer at all.

This is the plunker . The demo looks very much like the fiddle you linked. But let me explain a bit:

Lets go through the code.

d3.csv("data.csv", function(data){...}

This line is basically a way of D3 to access csv files. Do mind, if you try this locally on your machine, you will unknowingly violate the same-origin-policy and the example will not work.

You will also notice that all the D3 code is in this .csv callback function, the reason being that it is performed asynchronously.

The rest is pretty straightforward actually:

var values = [];
  var keys = []
  data.forEach(function(item){
    keys = d3.keys(item);
    var array = []
    for(var key in item) {
        array.push(item[key]);
    }
    values.push(array);
  });

These lines will extract the csv header (which i called keys) and it will also filter the resulting .csv data so that only the values remain. In order to fully understand what i mean by this, you should do a console.log() on the 'data' parameter you get from the callback. Then you will understand what the result object of the d3.csv function.

I made 2 examples: 1 is the html way, the other is using the svg way. In any case, D3 works the same.

To finish, i ll explain the following piece of code:

var tablerows = table.selectAll(".data")
                       .data(values)
                       .enter()
                       .append("tr")
                       .attr({
                         class:"data"
                       });

  var cells = tablerows.selectAll("td")
                        .data(function(d){return d;})
                        .enter()
                        .append("td")
                        .text(function(d) {return d;});

So, what you see here is d3 selecting DOM elements and bind them to that given data. You probably wonder about the following: How do you mean, selecting DOM elements? Those elements are not even there yet at the time you select them!

And you are right. This is one of the hard parts of D3, understanding its selections. Selecting with D3 can be understood in 2 contexts:

1) The DOM elements you are selecting are actually there. This context is the most straightforward one: the selection contains the actual dom elements. This feels a bit like jQuery. What you do with them can be very simple (like changing a class or something) or it can be depending on the data you want to bind or had already bound to them. More on data binding a bit further.

2) The DOM elements you are selecting are in the DOM (yet). This feels weird, right? When you select DOM elements that are not in the DOM, then your context is all about data. In this situation you need to think: What elements are not in the DOM yet, but would i really like to have in the DOM? Depending on the data you will bind to your selection, D3 will create them for you. This is how it goes in the code:

var tablerows = table.selectAll(".data")
                       .data(values)
                       .enter()
                       .append("tr")
                       .attr({
                         class:"data"
                       });

You can basically translate this code like this: I am selecting all the elements in the DOM (or not yet in the dom) that have the class "data". To that selection, I bind data (the array values, which contains 2 elements). I need d3 to check my data and check how many elements need to be added to the DOM. Since there are no '.data' elements there yet, and there are 2 items in my data array, the append() function will add 2 elements to the DOM. With the attr, i can specify the details of the DOM element.

Then there is only the point of data binding, which I will only touch lightely (because I don't know all that much about it either tbh). Check this:

var cells = tablerows.selectAll("td")
                        .data(function(d){return d;})
                        .enter()
                        .append("td")
                        .text(function(d) {return d;});

What is the d all about? That is the data bound to "g" elements from the previous piece of code. In that piece of code, I created 2 "g" elements, because i bound an array container 2 other arrays to my selection. D3 really binds this data to your elements. The pieces of data inside the "value" array happen to be arrays themselves! So, every "g" element created by D3 will have such an array bound to it. The "d" is how you would access that data in a function. So this line:

.data(function(d){return d;})

means: i want to bind to my selection: the data bound to the parent element (well, it may not be exactly like that, but in order to start to understand D3 a bit, i think its close enough).

So to wrap this up a little bit: what you should know about D3, selections and data:

D3 checks your selection and somewhat counts the elements that are already in the DOM. Then it counts the amount of data elements you want to bind to your selection.

Suppose you have selected 2 elements in the DOM and your data contains 4 elements, that means you have 2 'elements-to-be' . Those elements-to-be are sometimes called 'the enter selection' . You can reach those elements by doing the .enter() function. You can choose what to do with them, but most of the time, you will be appending them.

Suppose you have selected 4 elements in the DOM but your data only contains 2, you have 2 elements-to-be-removed, or sometimes called the 'exit selection'. Most of the time, you will be using .remove() on those elements to get them out of the DOM.

When you have 4 elements selected in the DOM, and your data has 4 items, then you can update the selected DOM elements with the data you want to bind to them. This is called the 'update selection' .

I hope it helped out, if you have more questions, please ask!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM