[英]d3 multiline chart from JSON
我有这个JSON结构:
[{
"city": "roma",
"giornata": [{"hour": 0, "vscore": 2.691172504799798, "sscore": 37476.67912706408}, {"hour": 1, "vscore": 2.691172504799798, "sscore": 37476.67912706408}, {"hour": 2, "vscore": 2.6911859886310534, "sscore": 37477.76228681598}, {"hour": 3, "vscore": 2.692891756586413, "sscore": 37633.63745016247}, {"hour": 4, "vscore": 2.7490858604464163, "sscore": 40331.835034215015}, {"hour": 5, "vscore": 3.6348376398556206, "sscore": 29087.830074293775}, {"hour": 6, "vscore": 5.227711033677134, "sscore": 40951.01373374646}, {"hour": 7, "vscore": 5.437638544676074, "sscore": 41884.0578795353}, {"hour": 8, "vscore": 5.478694300536231, "sscore": 41491.303030952506}, {"hour": 9, "vscore": 5.4692759563035125, "sscore": 41406.2244628412}, {"hour": 10, "vscore": 5.443814538954288, "sscore": 41843.69307948355}, {"hour": 11, "vscore": 5.422306701744998, "sscore": 41904.21264813825}, {"hour": 12, "vscore": 5.430029861802209, "sscore": 41834.62986331701}, {"hour": 13, "vscore": 5.4109556800533065, "sscore": 41794.032135620844}, {"hour": 14, "vscore": 5.40781751131936, "sscore": 41906.699275642364}, {"hour": 15, "vscore": 5.4276853171768575, "sscore": 42204.700654376065}, {"hour": 16, "vscore": 5.431391815372439, "sscore": 42038.98228259192}, {"hour": 17, "vscore": 5.452904669522696, "sscore": 42225.77758780385}, {"hour": 18, "vscore": 5.459166165306796, "sscore": 42521.80948063545}, {"hour": 19, "vscore": 5.4113071917201605, "sscore": 42211.7148629514}, {"hour": 20, "vscore": 5.346846713801516, "sscore": 40255.25859980825}, {"hour": 21, "vscore": 5.258902353621712, "sscore": 39863.6143315623}, {"hour": 22, "vscore": 5.099446294358522, "sscore": 38595.79782658543}, {"hour": 23, "vscore": 4.825210817812031, "sscore": 35445.99667251284}],
"totale_vscore": 4.732977155119956,
"totale_sscore": 39994.330896155014,
"pop": 2953570.1564810127
}, {
"city": "milan",
"giornata": [{"hour": 0, "vscore": 2.82848132753263, "sscore": 32951.656649915116}, {"hour": 1, "vscore": 2.989182437431815, "sscore": 22400.365091162155}, {"hour": 2, "vscore": 3.089781672302136, "sscore": 25970.908167900478}, {"hour": 3, "vscore": 3.079852593000065, "sscore": 26122.539536044023}, {"hour": 4, "vscore": 3.127878555095266, "sscore": 28533.06300816934}, {"hour": 5, "vscore": 3.433688887459625, "sscore": 31280.682050177216}, {"hour": 6, "vscore": 4.460403545073164, "sscore": 41143.18408624148}, {"hour": 7, "vscore": 4.676520890455807, "sscore": 40440.9468380336}, {"hour": 8, "vscore": 4.5650214131720945, "sscore": 40922.767810551035}, {"hour": 9, "vscore": 4.534050693834924, "sscore": 40604.83122991684}, {"hour": 10, "vscore": 4.475014854496835, "sscore": 42008.856192005565}, {"hour": 11, "vscore": 4.449355201432976, "sscore": 40234.6533377194}, {"hour": 12, "vscore": 4.479651286256149, "sscore": 42297.87576207919}, {"hour": 13, "vscore": 4.532114009807487, "sscore": 42846.236555682415}, {"hour": 14, "vscore": 4.521175500387353, "sscore": 41932.90288440584}, {"hour": 15, "vscore": 4.462502028191485, "sscore": 41718.30395828536}, {"hour": 16, "vscore": 4.46901281686112, "sscore": 41710.48122672351}, {"hour": 17, "vscore": 4.5388217291954, "sscore": 40768.24927687489}, {"hour": 18, "vscore": 4.5271592249042865, "sscore": 41346.4872610591}, {"hour": 19, "vscore": 4.525012398546656, "sscore": 40461.46407886699}, {"hour": 20, "vscore": 4.4785954581843335, "sscore": 38842.93096854251}, {"hour": 21, "vscore": 4.300929936708735, "sscore": 36595.34193318566}, {"hour": 22, "vscore": 4.157413373148136, "sscore": 34567.45808410202}, {"hour": 23, "vscore": 4.097682551344804, "sscore": 32583.34061363281}],
"totale_vscore": 4.116637599367636,
"totale_sscore": 37011.89694171986,
"pop": 2228858.085428001
}]
我需要创建一个d3折线图,其中每一行都是JSON的一个元素,例如:
“roma”的一行,X轴为“小时”,Y轴为“vscore”
“米兰”的第二行,X轴为“小时”,Y轴为“vscore”
和其他城市一样。
我很难从json动态创建d3.svg.line()。
现在我的代码只使用一行:
var margin = {
top: 20,
right: 20,
bottom: 50,
left: 40
},
width = 900 - margin.left - margin.right,
height = 290 - margin.top - margin.bottom;
// Set the ranges
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.innerTickSize(-height)
.outerTickSize(0)
.tickPadding(10);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left").innerTickSize(-width)
.outerTickSize(0)
.tickPadding(10);
// Define the line
//Here I don't know how to get line dynamically
var valueline = d3.svg.line()
.interpolate("basis")
.x(function (d) {
return x(d.hour);
})
.y(function (d) {
return y(d.vscore);
});
// Adds the svg canvas
var svg = d3.select("#dailyChart")
.append("svg")
// .call(zoom)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
d3.json("data/ranking_sscore.json", function(error, data) {
//Here I don't know how to cycle for get line from json
data = data[0].giornata
data.forEach(function (d) {
d.hour = d.hour;
d.vscore = +d.vscore;
});
x.domain(data.map(function (d) {
return d.hour;
}))
y.domain([0, d3.max(data,
function (d) {
return Math.max(d.vscore);
})]);
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data))
.style("stroke", 1);
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("y", 15)
.attr("x", 0)
.attr("dy", ".35em")
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
})
谢谢
D3可以为你做循环。
这是D3v5版本。
如果要为许多城市着色,可以使用color
序数比例,请参阅注释行(您需要定义color
)。
var margin = { top: 20, right: 20, bottom: 50, left: 40 }, svgWidth = 900, svgHeight = 290, width = svgWidth - margin.left - margin.right, height = svgHeight - margin.top - margin.bottom; var data = [{ "city": "roma", "giornata": [ {"hour": 0, "vscore": 2.691172504799798, "sscore": 37476.67912706408}, {"hour": 1, "vscore": 2.691172504799798, "sscore": 37476.67912706408}, {"hour": 2, "vscore": 2.6911859886310534, "sscore": 37477.76228681598}, {"hour": 3, "vscore": 2.692891756586413, "sscore": 37633.63745016247}, {"hour": 4, "vscore": 2.7490858604464163, "sscore": 40331.835034215015}, {"hour": 5, "vscore": 3.6348376398556206, "sscore": 29087.830074293775}, {"hour": 6, "vscore": 5.227711033677134, "sscore": 40951.01373374646}, {"hour": 7, "vscore": 5.437638544676074, "sscore": 41884.0578795353}, {"hour": 8, "vscore": 5.478694300536231, "sscore": 41491.303030952506}, {"hour": 9, "vscore": 5.4692759563035125, "sscore": 41406.2244628412}, {"hour": 10, "vscore": 5.443814538954288, "sscore": 41843.69307948355}, {"hour": 11, "vscore": 5.422306701744998, "sscore": 41904.21264813825}, {"hour": 12, "vscore": 5.430029861802209, "sscore": 41834.62986331701}, {"hour": 13, "vscore": 5.4109556800533065, "sscore": 41794.032135620844}, {"hour": 14, "vscore": 5.40781751131936, "sscore": 41906.699275642364}, {"hour": 15, "vscore": 5.4276853171768575, "sscore": 42204.700654376065}, {"hour": 16, "vscore": 5.431391815372439, "sscore": 42038.98228259192}, {"hour": 17, "vscore": 5.452904669522696, "sscore": 42225.77758780385}, {"hour": 18, "vscore": 5.459166165306796, "sscore": 42521.80948063545}, {"hour": 19, "vscore": 5.4113071917201605, "sscore": 42211.7148629514}, {"hour": 20, "vscore": 5.346846713801516, "sscore": 40255.25859980825}, {"hour": 21, "vscore": 5.258902353621712, "sscore": 39863.6143315623}, {"hour": 22, "vscore": 5.099446294358522, "sscore": 38595.79782658543}, {"hour": 23, "vscore": 4.825210817812031, "sscore": 35445.99667251284}], "totale_vscore": 4.732977155119956, "totale_sscore": 39994.330896155014, "pop": 2953570.1564810127 }, { "city": "milan", "giornata": [ {"hour": 0, "vscore": 2.82848132753263, "sscore": 32951.656649915116}, {"hour": 1, "vscore": 2.989182437431815, "sscore": 22400.365091162155}, {"hour": 2, "vscore": 3.089781672302136, "sscore": 25970.908167900478}, {"hour": 3, "vscore": 3.079852593000065, "sscore": 26122.539536044023}, {"hour": 4, "vscore": 3.127878555095266, "sscore": 28533.06300816934}, {"hour": 5, "vscore": 3.433688887459625, "sscore": 31280.682050177216}, {"hour": 6, "vscore": 4.460403545073164, "sscore": 41143.18408624148}, {"hour": 7, "vscore": 4.676520890455807, "sscore": 40440.9468380336}, {"hour": 8, "vscore": 4.5650214131720945, "sscore": 40922.767810551035}, {"hour": 9, "vscore": 4.534050693834924, "sscore": 40604.83122991684}, {"hour": 10, "vscore": 4.475014854496835, "sscore": 42008.856192005565}, {"hour": 11, "vscore": 4.449355201432976, "sscore": 40234.6533377194}, {"hour": 12, "vscore": 4.479651286256149, "sscore": 42297.87576207919}, {"hour": 13, "vscore": 4.532114009807487, "sscore": 42846.236555682415}, {"hour": 14, "vscore": 4.521175500387353, "sscore": 41932.90288440584}, {"hour": 15, "vscore": 4.462502028191485, "sscore": 41718.30395828536}, {"hour": 16, "vscore": 4.46901281686112, "sscore": 41710.48122672351}, {"hour": 17, "vscore": 4.5388217291954, "sscore": 40768.24927687489}, {"hour": 18, "vscore": 4.5271592249042865, "sscore": 41346.4872610591}, {"hour": 19, "vscore": 4.525012398546656, "sscore": 40461.46407886699}, {"hour": 20, "vscore": 4.4785954581843335, "sscore": 38842.93096854251}, {"hour": 21, "vscore": 4.300929936708735, "sscore": 36595.34193318566}, {"hour": 22, "vscore": 4.157413373148136, "sscore": 34567.45808410202}, {"hour": 23, "vscore": 4.097682551344804, "sscore": 32583.34061363281}], "totale_vscore": 4.116637599367636, "totale_sscore": 37011.89694171986, "pop": 2228858.085428001 }]; // Set the ranges var x = d3.scaleLinear().range([0, width]); var y = d3.scaleLinear().range([height, 0]); // Define the axes var xAxis = d3.axisBottom() .scale(x) .tickSize(-height); var yAxis = d3.axisLeft() .scale(y) .tickSize(-width); var valueline = d3.line() .curve(d3.curveBasis) .x( d => x(d.hour) ) .y( d => y(d.vscore) ); // Adds the svg canvas var g = d3.select("#dailyChart") .append("svg") // .call(zoom) .attr("width", svgWidth) .attr("height", svgHeight) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // d3.json("data/ranking_sscore.json", drawGraph ); drawGraph(null, data); function drawGraph(error, data) { x.domain(d3.extent(data[0].giornata, d => d.hour)); y.domain([0, d3.max(data, d => d3.max(d.giornata, g => g.vscore) ) + 1 ]); // Add the X Axis g.append("g") .attr("class", "x axis") .attr("transform", `translate(0,${height})`) .call(xAxis) .selectAll("text") .attr("y", 15) .attr("x", 0) .attr("dy", ".35em"); // Add the Y Axis g.append("g") .attr("class", "y axis") .call(yAxis); g.selectAll(".city") .data(data) .enter() .append("path") .attr('class', d => 'city' + ' ' + d.city) //.style("stroke", (d,i) => color(i) ) .attr("d", d => valueline(d.giornata) ); }
.roma { fill:none; stroke:red; } .milan { fill:none; stroke:blue; }
<script src="https://d3js.org/d3.v5.min.js"></script> <div id="dailyChart"></div>
你必须首先在你的主阵列上循环,然后在每个阵列“gionarta”上循环
window.addEventListener('load', function () { var margin = { top: 20, right: 20, bottom: 50, left: 40 }, width = 900 - margin.left - margin.right, height = 290 - margin.top - margin.bottom; // Set the ranges var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1); var y = d3.scale.linear().range([height, 0]); // Define the axes var xAxis = d3.svg.axis() .scale(x) .orient("bottom") .innerTickSize(-height) .outerTickSize(0) .tickPadding(10); var yAxis = d3.svg.axis() .scale(y) .orient("left").innerTickSize(-width) .outerTickSize(0) .tickPadding(10); // Define the line //Here I don't know how to get line dynamically var valueline = d3.svg.line() .interpolate("basis") .x(function (d) { return x(d.hour); }) .y(function (d) { return y(d.vscore); }); // Adds the svg canvas var svg = d3.select("#dailyChart") .append("svg") // .call(zoom) .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform","translate(" + margin.left + "," + margin.top + ")"); //Here is the relevant part first loop on your main array data.forEach(function(el,index){ items = el.giornata; // then on each array giornata items.forEach(function (d) { d.hour = d.hour; d.vscore = +d.vscore; }); x.domain(items.map(function (d) { return d.hour; })) y.domain([0, d3.max(items, function (d) { return Math.max(d.vscore); })]); // Add the valueline path. svg.append("path") .attr("class", "line roma "+data[index].city) .attr("d", valueline(items)) .style("stroke", 1); }); // Add the X Axis svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .attr("y", 15) .attr("x", 0) .attr("dy", ".35em") // Add the Y Axis svg.append("g") .attr("class", "y axis") .call(yAxis); }); var data = [{ "city": "roma", "giornata": [{"hour": 0, "vscore": 2.691172504799798, "sscore": 37476.67912706408}, {"hour": 1, "vscore": 2.691172504799798, "sscore": 37476.67912706408}, {"hour": 2, "vscore": 2.6911859886310534, "sscore": 37477.76228681598}, {"hour": 3, "vscore": 2.692891756586413, "sscore": 37633.63745016247}, {"hour": 4, "vscore": 2.7490858604464163, "sscore": 40331.835034215015}, {"hour": 5, "vscore": 3.6348376398556206, "sscore": 29087.830074293775}, {"hour": 6, "vscore": 5.227711033677134, "sscore": 40951.01373374646}, {"hour": 7, "vscore": 5.437638544676074, "sscore": 41884.0578795353}, {"hour": 8, "vscore": 5.478694300536231, "sscore": 41491.303030952506}, {"hour": 9, "vscore": 5.4692759563035125, "sscore": 41406.2244628412}, {"hour": 10, "vscore": 5.443814538954288, "sscore": 41843.69307948355}, {"hour": 11, "vscore": 5.422306701744998, "sscore": 41904.21264813825}, {"hour": 12, "vscore": 5.430029861802209, "sscore": 41834.62986331701}, {"hour": 13, "vscore": 5.4109556800533065, "sscore": 41794.032135620844}, {"hour": 14, "vscore": 5.40781751131936, "sscore": 41906.699275642364}, {"hour": 15, "vscore": 5.4276853171768575, "sscore": 42204.700654376065}, {"hour": 16, "vscore": 5.431391815372439, "sscore": 42038.98228259192}, {"hour": 17, "vscore": 5.452904669522696, "sscore": 42225.77758780385}, {"hour": 18, "vscore": 5.459166165306796, "sscore": 42521.80948063545}, {"hour": 19, "vscore": 5.4113071917201605, "sscore": 42211.7148629514}, {"hour": 20, "vscore": 5.346846713801516, "sscore": 40255.25859980825}, {"hour": 21, "vscore": 5.258902353621712, "sscore": 39863.6143315623}, {"hour": 22, "vscore": 5.099446294358522, "sscore": 38595.79782658543}, {"hour": 23, "vscore": 4.825210817812031, "sscore": 35445.99667251284}], "totale_vscore": 4.732977155119956, "totale_sscore": 39994.330896155014, "pop": 2953570.1564810127 }, { "city": "milan", "giornata": [{"hour": 0, "vscore": 2.82848132753263, "sscore": 32951.656649915116}, {"hour": 1, "vscore": 2.989182437431815, "sscore": 22400.365091162155}, {"hour": 2, "vscore": 3.089781672302136, "sscore": 25970.908167900478}, {"hour": 3, "vscore": 3.079852593000065, "sscore": 26122.539536044023}, {"hour": 4, "vscore": 3.127878555095266, "sscore": 28533.06300816934}, {"hour": 5, "vscore": 3.433688887459625, "sscore": 31280.682050177216}, {"hour": 6, "vscore": 4.460403545073164, "sscore": 41143.18408624148}, {"hour": 7, "vscore": 4.676520890455807, "sscore": 40440.9468380336}, {"hour": 8, "vscore": 4.5650214131720945, "sscore": 40922.767810551035}, {"hour": 9, "vscore": 4.534050693834924, "sscore": 40604.83122991684}, {"hour": 10, "vscore": 4.475014854496835, "sscore": 42008.856192005565}, {"hour": 11, "vscore": 4.449355201432976, "sscore": 40234.6533377194}, {"hour": 12, "vscore": 4.479651286256149, "sscore": 42297.87576207919}, {"hour": 13, "vscore": 4.532114009807487, "sscore": 42846.236555682415}, {"hour": 14, "vscore": 4.521175500387353, "sscore": 41932.90288440584}, {"hour": 15, "vscore": 4.462502028191485, "sscore": 41718.30395828536}, {"hour": 16, "vscore": 4.46901281686112, "sscore": 41710.48122672351}, {"hour": 17, "vscore": 4.5388217291954, "sscore": 40768.24927687489}, {"hour": 18, "vscore": 4.5271592249042865, "sscore": 41346.4872610591}, {"hour": 19, "vscore": 4.525012398546656, "sscore": 40461.46407886699}, {"hour": 20, "vscore": 4.4785954581843335, "sscore": 38842.93096854251}, {"hour": 21, "vscore": 4.300929936708735, "sscore": 36595.34193318566}, {"hour": 22, "vscore": 4.157413373148136, "sscore": 34567.45808410202}, {"hour": 23, "vscore": 4.097682551344804, "sscore": 32583.34061363281}], "totale_vscore": 4.116637599367636, "totale_sscore": 37011.89694171986, "pop": 2228858.085428001 }]
.roma{ fill:none; stroke:red; } .milan{ fill:none; stroke:blue; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="dailyChart"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.