Last active
March 29, 2019 20:04
-
-
Save joshbirk/08be97d92b91c3bdc9e1 to your computer and use it in GitHub Desktop.
Lightning Chart Component w/ D3.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function plumb(raw_data,data) { | |
this.raw_data = raw_data; | |
this.data = data; | |
return this; | |
} | |
plumb.prototype.keyPlumber = function() {} | |
plumb.prototype.generateKey = function(plumber) { | |
this.keyPlumber = plumber; | |
this.data = []; | |
var data_plumb = this; | |
this.raw_data.forEach(function(record) { | |
data_plumb.data[data_plumb.keyPlumber(record)] = {}; | |
}); | |
return this; | |
} | |
plumb.prototype.meanField = function(field,label) { | |
var data_plumb = this; | |
this.raw_data.forEach(function(record) { | |
if(data_plumb.data[data_plumb.keyPlumber(record)][label] === undefined) { //this assumes first run | |
data_plumb.data[data_plumb.keyPlumber(record)][label] = 0; | |
data_plumb.data[data_plumb.keyPlumber(record)]["keyCount"] = 0; | |
} | |
data_plumb.data[data_plumb.keyPlumber(record)][label] += record[field]; | |
data_plumb.data[data_plumb.keyPlumber(record)]["keyCount"]++; | |
}); | |
this.data.forEach(function(record) { | |
// fieldCount = data_plumb.raw_data.length / data_plumb.data.length; | |
record[label] /= record["keyCount"]; | |
console.log(record[label]); | |
}); | |
return this; | |
} | |
plumb.prototype.maxField = function(field,label) { | |
var data_plumb = this; | |
this.raw_data.forEach(function(record) { | |
if(data_plumb.data[data_plumb.keyPlumber(record)][label] === undefined || record[field] > data_plumb.data[data_plumb.keyPlumber(record)][label]) { | |
data_plumb.data[data_plumb.keyPlumber(record)][label] = record[field]; | |
} | |
}); | |
return this; | |
} | |
plumb.prototype.minField = function(field,label) { | |
var data_plumb = this; | |
this.raw_data.forEach(function(record) { | |
if(data_plumb.data[data_plumb.keyPlumber(record)][label] === undefined || record[field] < data_plumb.data[data_plumb.keyPlumber(record)][label]) { | |
data_plumb.data[data_plumb.keyPlumber(record)][label] = record[field]; | |
} | |
}); | |
return this; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public with sharing class SpeedTestController { | |
@AuraEnabled | |
public static List< SpeedTest__c > getData() { | |
List<SpeedTest__c> speeds = [SELECT ID, TimeString__c,Download__c,Upload__c from SpeedTest__c LIMIT 1000]; | |
return speeds; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<aura:component controller="SpeedTestController" > | |
<ltng:require scripts="/resource/jquery,/resource/d3,/resource/plumb" | |
afterScriptsLoaded="{!c.getSpeeds}"/> | |
<div id="chart"></div> | |
</aura:component> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
({ | |
getSpeeds : function(component, event, helper) { | |
var speeds = new Array(); | |
var current_offset = 100; | |
var done = false; | |
var transformed_speeds = []; | |
var speed_plumb = {}; | |
var action = component.get("c.getData"); | |
action.setCallback(this, function(a) { | |
speeds = a.getReturnValue(); | |
speed_plumb = new plumb(speeds); | |
helper.plumbData(speed_plumb); | |
helper.drawData(speed_plumb); | |
}); | |
$A.enqueueAction(action); | |
} | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
({ | |
plumbData : function(speed_plumb) { | |
speed_plumb.generateKey(function(speed) { | |
var hour = speed.TimeString__c.split(" ")[1]; | |
hour = hour.split(":")[0]; | |
hour = parseInt(hour); | |
return hour; | |
}).meanField("Download__c","DownloadSpeed") | |
.maxField("Download__c","MaxDownload") | |
.minField("Download__c","MinDownload") | |
.meanField("Download__c","MeanDownload"); | |
}, | |
createArc : function(time,speed, svg) { | |
if(!speed || !speed.DownloadSpeed) {return;} | |
var gradient = ["#F50D00","#D91319","#BE1A32","#A3214C","#882865","#6C2E7F","#513598","#363CB2","#1B43CB","#004AE5","#004AE5","#004AE5","#004AE5"]; | |
var peak_color = "#FFDF99"; | |
var startAngle = time * 15; | |
var endAngle = startAngle + 15; | |
var arc = d3.svg.arc() | |
.innerRadius(40) | |
.outerRadius(150) | |
.startAngle(startAngle * (Math.PI/180)) //converting from degs to radians | |
.endAngle(endAngle * (Math.PI/180)) //just radians | |
svg.append("path") | |
.attr("d", arc) | |
.attr("class", "hour-arc") | |
.attr("id", "hour"+String(time)) | |
.attr("fill", function (d, i) { return gradient[Math.round(speed.DownloadSpeed)]; }) | |
.attr("stroke", peak_color) | |
.attr("transform", "translate(175,175)"); | |
var text = svg.append("text") | |
.attr("x", 5) | |
.attr("dy", 24); | |
text.append("textPath") | |
.attr("class", "hour-arc") | |
.attr("stroke","white") | |
.style("fill","white") | |
.attr("font-family","Verdana") | |
.attr("font-size","24") | |
.attr("xlink:href","#hour"+String(time)) | |
.text(String(Math.round(speed.MeanDownload))); | |
var text_speed = svg.append("text") | |
.attr("x", 10) | |
.attr("dy", 80); | |
text_speed.append("textPath") | |
.attr("class", "hour-arc") | |
.attr("stroke",peak_color) | |
.attr("font-family","Verdana") | |
.attr("font-size","12") | |
.attr("xlink:href","#hour"+String(time)) | |
.text(String(time)); | |
}, | |
drawData : function(speed_plumb) { | |
var svg = d3.select("#chart").append("svg") | |
.attr("preserveAspectRatio", "xMidYMid") | |
.attr("viewBox", "-50 -50 1200 1200") | |
.attr("width", 1200) | |
.attr("height", 1200); | |
var peak_color = "#FFDF99"; | |
//Play Time | |
var startAngle = 20 * 15; | |
var endAngle = startAngle + 75; | |
var arc = d3.svg.arc() | |
.innerRadius(20) | |
.outerRadius(200) | |
.startAngle(startAngle * (Math.PI/180)) //converting from degs to radians | |
.endAngle(endAngle * (Math.PI/180)) //just radians | |
svg.append("path") | |
.attr("d", arc) | |
.attr("stroke","black") | |
.attr("id", "peaktime") | |
.attr("fill", function (d, i) { return peak_color; }) | |
.attr("transform", "translate(175,175)"); | |
var text = svg.append("text") | |
.attr("x", 14) | |
.attr("dy", 14); | |
text.append("textPath") | |
.attr("stroke","black") | |
.attr("font-family","Verdana") | |
.attr("font-size","12") | |
.attr("xlink:href","#peaktime") | |
.text("Online Gaming"); | |
//Sleep Time | |
startAngle = 24 * 15; | |
endAngle = startAngle + 135; | |
arc = d3.svg.arc() | |
.innerRadius(20) | |
.outerRadius(200) | |
.startAngle(startAngle * (Math.PI/180)) //converting from degs to radians | |
.endAngle(endAngle * (Math.PI/180)) //just radians | |
svg.append("path") | |
.attr("d", arc) | |
.attr("stroke","black") | |
.attr("id", "sleeptime") | |
.attr("fill", function (d, i) { return peak_color; }) | |
.attr("transform", "translate(175,175)"); | |
text = svg.append("text") | |
.attr("x", 14) | |
.attr("dy", 14); | |
text.append("textPath") | |
.attr("stroke","black") | |
.attr("font-family","Verdana") | |
.attr("font-size","12") | |
.attr("xlink:href","#sleeptime") | |
.text("Sleeping"); | |
//Work Time | |
startAngle = 9 * 15; | |
endAngle = startAngle + 135; | |
arc = d3.svg.arc() | |
.innerRadius(20) | |
.outerRadius(200) | |
.startAngle(startAngle * (Math.PI/180)) //converting from degs to radians | |
.endAngle(endAngle * (Math.PI/180)) //just radians | |
svg.append("path") | |
.attr("d", arc) | |
.attr("stroke","black") | |
.attr("id", "worktime") | |
.attr("fill", function (d, i) { return peak_color; }) | |
.attr("transform", "translate(175,175)"); | |
text = svg.append("text") | |
.attr("x", 14) | |
.attr("dy", 14); | |
text.append("textPath") | |
.attr("stroke","black") | |
.attr("font-family","Verdana") | |
.attr("font-size","12") | |
.attr("xlink:href","#worktime") | |
.text("Working"); | |
//Netflix Time | |
startAngle = 18 * 15; | |
endAngle = startAngle + 30; | |
arc = d3.svg.arc() | |
.innerRadius(20) | |
.outerRadius(200) | |
.startAngle(startAngle * (Math.PI/180)) //converting from degs to radians | |
.endAngle(endAngle * (Math.PI/180)) //just radians | |
svg.append("path") | |
.attr("d", arc) | |
.attr("stroke","black") | |
.attr("id", "netflix") | |
.attr("fill", function (d, i) { return peak_color; }) | |
.attr("transform", "translate(175,175)"); | |
text = svg.append("text") | |
.attr("x", 14) | |
.attr("dy", 14); | |
text.append("textPath") | |
.attr("stroke","black") | |
.attr("font-family","Verdana") | |
.attr("font-size","12") | |
.attr("xlink:href","#netflix") | |
.text("Netflix"); | |
//refresh | |
d3.selectAll(".hour-arc").remove() | |
for(var i = 0; i < speed_plumb.data.length; i++) { | |
this.createArc(i,speed_plumb.data[i],svg); | |
} | |
} | |
}) |
Thanks joshbirk for the method os tagging the svg to a
!
davidrobertslogicom - Did you get an answer on this issue with the Callback()? Thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I am new to D3 and want to learn it. I started by implementing your code but getting the below error. Also, I created a custom object named SpeedTest__c.
Error in $A.getCallback() [plumb is not defined]
Callback failed: apex://SpeedTestController/ACTION$getData
Could you please help me to resolve it?
Thanks in advance !
Piyush