Hi all,
I am trying to display data using an XY chart from an infotable on Thingworx. I am aware that I can just use the existing XY chart widget in Thingworx but it does not meet the requirements which I need for a task. Therefore, I have decided to use d3.js to fulfill my requirements.
The image shown below is what I have coded using d3.js and imported to Thingworx. However, the data values are hard-coded and that is not what I want. I want the values of XAxis and ASensor to be displayed on my XY chart but I am unable to do so despite binding the infotable with my data. I have attached the relevant files for reference. Any help will be greatly appreciated!
Solved! Go to Solution.
Hi @PEHOWE, thanks for the reply. To answer your questions:
EDIT 1: I used the debugger in developer tools and found the following errors.
It seems like the data from the infotable is passed into the drawChart function correctly but there is some error in the drawing of circle and line path. The relevant code is as shown.
// interpolator for X axis -- inner plot region
var x = d3.scaleLinear()
.domain([ d3.min(data, function(d){ return d.LegReaction; }),
d3.max(data, function (d){ return d.LegReaction; }) ])
.range([0,innerWidth])
.nice();
// interpolator for Y axis -- inner plot region
var y = d3.scaleLinear()
.domain([ d3.min(data, function(d){ return d.LegPenetration; }),
d3.max(data, function (d){ return d.LegPenetration; }) ])
.range([0,innerHeight])
.nice();
// plot a circle at each data location g.selectAll(".dot")
.data(data) .enter().append("circle") .attr("class", "dot") .attr("cx", function(d) { return x(d.x); } ) //should be d.LegReaction .attr("cy", function(d) { return y(d.y); } ) //should be d.LegPenetration .attr("r", 5); //the line function for path var lineFunction = d3.line() .x(function(d) {return x(d.x); }) //should be d.LegReaction .y(function(d) {return y(d.y); }) //should be d.LegPenetration .curve(d3.curveLinear); //plot line var path = g.append("path") .attr("d", lineFunction(data)) .attr("stroke", "blue") .attr("stroke-width", 2) .attr("fill", "none");
EDIT 2: I was able to figure out the error and added comments to the code above to show where I went wrong.
Hello @kahmeng96 ,
I have not used the d3 extension. I did take a quick look at the d3timeseries extension which you included in your post. Data is supplied to the grid from a service as an infotable. If your service is providing dynamic data then your chart will display that data. What are the input devices which are supplying data?
Hi @PEHOWE,
Thanks for the reply. I have made some changes to the infotable, for it to only contain 2 values: leg penetration and spudcan reaction. The input device supplying the data is the Thingworx platform itself, where values of leg penetration and spudcan reaction are entered into the mashup composer in Thingworx as shown in the photos.
The issue now is that I cannot seem to get the values of this data to display on my custom XY chart widget as the code in runtime.js requires changing. I have tried coding using the code of the existing XY chart widget built in Thingworx but to no avail. I am using d3.js to draw the chart for my requirements thus I can't use the TW.ChartLibrary to display the data like what the existing XY chart does. Any advice on how to start modifying the code in my zipfile to make this work?
The Extension you uploaded displays nothing in my test environment.
Hi @PEHOWE, thanks for the reply. To answer your questions:
EDIT 1: I used the debugger in developer tools and found the following errors.
It seems like the data from the infotable is passed into the drawChart function correctly but there is some error in the drawing of circle and line path. The relevant code is as shown.
// interpolator for X axis -- inner plot region
var x = d3.scaleLinear()
.domain([ d3.min(data, function(d){ return d.LegReaction; }),
d3.max(data, function (d){ return d.LegReaction; }) ])
.range([0,innerWidth])
.nice();
// interpolator for Y axis -- inner plot region
var y = d3.scaleLinear()
.domain([ d3.min(data, function(d){ return d.LegPenetration; }),
d3.max(data, function (d){ return d.LegPenetration; }) ])
.range([0,innerHeight])
.nice();
// plot a circle at each data location g.selectAll(".dot")
.data(data) .enter().append("circle") .attr("class", "dot") .attr("cx", function(d) { return x(d.x); } ) //should be d.LegReaction .attr("cy", function(d) { return y(d.y); } ) //should be d.LegPenetration .attr("r", 5); //the line function for path var lineFunction = d3.line() .x(function(d) {return x(d.x); }) //should be d.LegReaction .y(function(d) {return y(d.y); }) //should be d.LegPenetration .curve(d3.curveLinear); //plot line var path = g.append("path") .attr("d", lineFunction(data)) .attr("stroke", "blue") .attr("stroke-width", 2) .attr("fill", "none");
EDIT 2: I was able to figure out the error and added comments to the code above to show where I went wrong.