简体   繁体   English

d3.js中的双Y轴折线图,没有外部数据

[英]Dual Y axis line chart in d3.js without external data

I am new to d3 (and javascript and html), but please bear with me. 我是d3(以及javascript和html)的新手,但请耐心等待。 My overall goal is to implement some d3 charts within FileMaker Pro (FMP - a relational database) and in particular its mobile counterpart FileMaker Go. 我的总体目标是在FileMaker Pro(FMP-关系数据库)中实现某些d3图表,尤其是在其移动副本FileMaker Go中。 This is because the charting options within FMP are limited. 这是因为FMP中的图表选项受到限制。 FMP does provide a web viewer that can render url's, or html and javascript code stored locally without needing an internet connection. FMP确实提供了一个Web查看器,可以呈现本地存储的url或html和javascript代码,而无需Internet连接。 I have replicated some examples provided on the d3 site, and wish to replicate this example but without having to resort to an external csv file: 我已经复制了d3网站上提供的一些示例,并希望复制此示例,但不必诉诸外部CSV文件:

http://bl.ocks.org/d3noob/e34791a32a54e015f57d http://bl.ocks.org/d3noob/e34791a32a54e015f57d

I have replicated the above example in a browser using an external csv file, but not yet in FMP. 我已经在使用外部csv文件的浏览器中复制了上面的示例,但尚未在FMP中复制。

I have attempted to follow some other examples where the data is embedded within the d3 code, but without success. 我尝试遵循其他一些将数据嵌入d3代码中的示例,但没有成功。 FMP allows me to to undertake calculations/text substitutions that will structure the data in the "correct" format and insert it within the d3 code, allowing the chart to update dynamically. FMP允许我进行计算/文本替换,将以“正确”格式构造数据并将其插入d3代码中,从而使图表可以动态更新。 This also applies to the d3 libraries. 这也适用于d3库。 I have applied this successfully to: 我已成功将此应用到:

http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6 http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6

Based on the d3noob example above, and reading on how "inline" data should be structured within the d3 code, I have come up with the following code, but it doesn't work. 基于上面的d3noob示例,并阅读了在d3代码中应如何构造“内联”数据,我想出了以下代码,但它不起作用。 I have modified the code for the x axis to allow for continuous data rather than dates, and included my data rather than that of the original example. 我已经修改了x轴的代码,以允许连续数据而不是日期,并且包括了我的数据而不是原始示例的数据。

Can someone advise me as to how the d3 code and data should be structured to function with "inline" data? 有人可以建议我如何将d3代码和数据构造为与“内联”数据一起使用吗? Additionally, I would like to achieve a single vertical line for the "open" data series (y1 - second or right hand y axis) that identifies the maximum value for that data series. 此外,我想为“开放”数据系列(y1-第二个或右手y轴)实现一条垂直线,以标识该数据系列的最大值。 It would be a different colour and rise vertically from the appropriate x value (where y1 = 0) to the peak of the curve (y1=1300, x=25 in the data below). 这将是另一种颜色,并从适当的x值(其中y1 = 0)垂直上升到曲线的峰值(在以下数据中为y1 = 1300,x = 25)。

Any help would be greatly appreciated - thanks in advance 任何帮助将不胜感激-预先感谢

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body { font: 12px Arial;}

path { 
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>

<script>

var margin = {top: 30, right: 40, bottom: 30, left: 50},
    width = 600 - margin.left - margin.right,
    height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.scale.linear().range([0, width]);
var y0 = d3.scale.linear().range([height, 0]);
var y1 = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(10);

var yAxisLeft = d3.svg.axis().scale(y0)
    .orient("left").ticks(5);

var yAxisRight = d3.svg.axis().scale(y1)
    .orient("right").ticks(5); 

var valueline = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y0(d.close); });

var valueline2 = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y1(d.open); });

var svg = d3.select("body")
    .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
    .append("g")
        .attr("transform", 
              "translate(" + margin.left + "," + margin.top + ")");

// Get the data
var data = [
{date: "0",close: "59.8",open: "897"},
{date: "1",close: "63.3",open: "943.5"},
{date: "2",close: "66.6",open: "988"},
{date: "3",close: "69.5",open: "1025.5"},
{date: "4",close: "72.2",open: "1061"},
{date: "5",close: "74.7",open: "1092.5"},
{date: "6",close: "76.9",open: "1119.5"},
{date: "7",close: "79",open: "1146"},
{date: "8",close: "80.8",open: "1167"},
{date: "9",close: "82.5",open: "1187.5"},
{date: "10",close: "84.1",open: "1205.5"},
{date: "11",close: "85.5",open: "1220.5"},
{date: "12",close: "86.8",open: "1235"},
{date: "13",close: "87.9",open: "1245.5"},
{date: "14",close: "89",open: "1257"},
{date: "15",close: "90",open: "1266"},
{date: "16",close: "90.9",open: "1273.5"},
{date: "17",close: "91.7",open: "1280.5"},
{date: "18",close: "92.4",open: "1285"},
{date: "19",close: "93.1",open: "1290.5"},
{date: "20",close: "93.7",open: "1293.5"},
{date: "21",close: "94.3",open: "1296.5"},
{date: "22",close: "94.8",open: "1299"},
{date: "23",close: "95.2",open: "1299"},
{date: "24",close: "95.6",open: "1299.5"},
{date: "25",close: "96",open: "1300"},
{date: "26",close: "96.4",open: "1299.6"},
{date: "27",close: "96.7",open: "1299.5"},
{date: "28",close: "97",open: "1298"},
{date: "29",close: "97.3",open: "1297.5"},
{date: "30",close: "97.5",open: "1294.5"},
{date: "31",close: "97.7",open: "1291.5"},
{date: "32",close: "97.9",open: "1289.5"},
{date: "33",close: "98.1",open: "1286.5"},
{date: "34",close: "98.3",open: "1284.5"},
{date: "35",close: "98.4",open: "1280"},
{date: "36",close: "98.6",open: "1277"},
{date: "37",close: "98.7",open: "1273.5"},
{date: "38",close: "98.8",open: "1269"},
{date: "39",close: "98.9",open: "1265.5"},
{date: "40",close: "99",open: "1261"},
{date: "41",close: "99.1",open: "1256.5"},
{date: "42",close: "99.2",open: "1253"},
{date: "43",close: "99.3",open: "1248.5"},
{date: "44",close: "99.3",open: "1243.5"},
{date: "45",close: "99.4",open: "1239"},
{date: "46",close: "99.4",open: "1233"},
{date: "47",close: "99.5",open: "1229.5"},
{date: "48",close: "99.5",open: "1223.5"},
{date: "49",close: "99.6",open: "1220"},
{date: "50",close: "99.6",open: "1214"},
{date: "51",close: "99.6",open: "1208"},
{date: "52",close: "99.7",open: "1204.5"},
{date: "53",close: "99.7",open: "1198.5"},
{date: "54",close: "99.7",open: "1193.5"},
{date: "55",close: "99.8",open: "1189"},
{date: "56",close: "99.8",open: "1183"},
{date: "57",close: "99.8",open: "1178"},
{date: "58",close: "99.8",open: "1172"},
{date: "59",close: "99.8",open: "1167"},
{date: "60",close: "99.8",open: "1161"},
{date: "61",close: "99.9",open: "1156.5"},
{date: "62",close: "99.9",open: "1151.5"},
{date: "63",close: "99.9",open: "1145.5"},
{date: "64",close: "99.9",open: "1140.5"},
{date: "65",close: "99.9",open: "1134.5"},
{date: "66",close: "99.9",open: "1128.5"},
{date: "67",close: "99.9",open: "1123.5"},
{date: "68",close: "99.9",open: "1117.5"},
{date: "69",close: "99.9",open: "1112.5"},
{date: "70",close: "99.9",open: "1106.5"},
{date: "71",close: "99.9",open: "1100.5"},
{date: "72",close: "99.9",open: "1095.5"},
{date: "73",close: "100",open: "1091"},
{date: "74",close: "100",open: "1086"},
{date: "75",close: "100",open: "1080"},
{date: "76",close: "100",open: "1074"},
{date: "77",close: "100",open: "1069"},
{date: "78",close: "100",open: "1063"},
{date: "79",close: "100",open: "1058"},
{date: "80",close: "100",open: "1052"},
{date: "81",close: "100",open: "1046"},
{date: "82",close: "100",open: "1041"},
{date: "83",close: "100",open: "1035"},
{date: "84",close: "100",open: "1030"},
{date: "85",close: "100",open: "1024"},
{date: "86",close: "100",open: "1018"},
{date: "87",close: "100",open: "1013"},
{date: "88",close: "100",open: "1007"},
{date: "89",close: "100",open: "1002"},
{date: "90",close: "100",open: "996"},
{date: "91",close: "100",open: "990"},
{date: "92",close: "100",open: "985"},
{date: "93",close: "100",open: "979"},
{date: "94",close: "100",open: "974"},
{date: "95",close: "100",open: "968"},
{date: "96",close: "100",open: "962"},
{date: "97",close: "100",open: "957"},
{date: "98",close: "100",open: "951"},
{date: "99",close: "100",open: "946"},
{date: "100",close: "100",open: "940"},
];

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y0.domain([0, d3.max(data, function(d) {
        return Math.max(d.close); })]); 
    y1.domain([0, d3.max(data, function(d) { 
        return Math.max(d.open); })]);

    svg.append("path")        // Add the valueline path.
        .attr("d", valueline(data));

    svg.append("path")        // Add the valueline2 path.
        .style("stroke", "red")
        .attr("d", valueline2(data));

    svg.append("g")            // Add the X Axis
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.append("g")
        .attr("class", "y axis")
        .style("fill", "steelblue")
        .call(yAxisLeft);   

    svg.append("g")             
        .attr("class", "y axis")    
        .attr("transform", "translate(" + width + " ,0)")   
        .style("fill", "red")       
        .call(yAxisRight);

});

</script>
</body>

I was able to get your code working after adjusting one line: 调整一行后,我就能使您的代码正常工作:

http://jsfiddle.net/spanndemic/tyLvshfa/ http://jsfiddle.net/spanndemic/tyLvshfa/

There is an extra }); 有一个额外的}); at the end of the script, which is commented out in the above fiddle: 在脚本的末尾,在上面的小提琴中被注释掉了:

svg.append("g")             
    .attr("class", "y axis")    
    .attr("transform", "translate(" + width + " ,0)")   
    .style("fill", "red")       
    .call(yAxisRight);

//});

Update: 更新:

Example of how to draw a line at the max data value... you have to find the object in the array that has the maximum 'open' value, then draw a line based of the value. 如何以最大数据值绘制直线的示例...您必须在数组中找到具有最大“打开”值的对象,然后根据该值绘制一条直线。

Updated fiddle: http://jsfiddle.net/spanndemic/tyLvshfa/ 更新的提琴: http : //jsfiddle.net/spanndemic/tyLvshfa/

Additional Code: 附加代码:

// get the data object that has the max;
var openMax = 0;
var openMaxData;
data.forEach(function(el, i){
    if (parseInt(el.open) > openMax) {
        openMaxData = el;
        openMax = el.open;
    }
});

// append the line
svg.append("line")
    .attr("class", "maximum")
    .attr("x1", x(openMaxData.date))
    .attr("x2", x(openMaxData.date))
    .attr("y1", 0)
    .attr("y2", height);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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