首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AngularJS:链接函数中带有D3图表的指令只工作一次

AngularJS:链接函数中带有D3图表的指令只工作一次
EN

Stack Overflow用户
提问于 2016-06-10 13:11:44
回答 1查看 241关注 0票数 0

我创建了一个AngularJS指令,其中包含一个D3图表,如下所示:

代码语言:javascript
复制
 angular.module('main', [''])

    .directive('barChart', function() {

        return {

            restrict: 'E',
            replace: true,
            scope: {
            },
            template: '<svg class="chart" width="250" height="100"></svg>',
            link: function (scope, element, attrs, fn) {

            var d3 = window.d3;

             var data = {
             labels: [
               'LY', 'TY'
             ],
             series: [{
               label: 'LY',
               values: [2.8]
             }, {
               label: 'TY',
               values: [3.2]
             }]
           };


        var chartWidth = 150,
            barHeight = 30,
            groupHeight = barHeight,
            gapBetweenGroups = -10,
            spaceForLabels = 50,
            spaceForLegend = 50;

        // Zip the series data together (first values, second values, etc.)
        var zippedData = [];
        for (var i = 0; i < data.labels.length; i++) {
            for (var j = 0; j < data.series.length; j++) {
                zippedData.push(data.series[i].values[j]);
            }
        }

        // Color scale
        var color = d3.scale.category20();
        var chartHeight = barHeight * zippedData.length + gapBetweenGroups * data.labels.length;

        var x, y, yAxis, chart, bar;

        function setChartParameters() {
            x = d3.scale.linear()
                .domain([0, d3.max(zippedData)])
                .range([0, chartWidth]);

            y = d3.scale.linear()
                .range([chartHeight + gapBetweenGroups, 0]);

            yAxis = d3.svg.axis()
                .scale(y)
                .tickFormat('')
                .tickSize(0)
                .orient("left");

            // Specify the chart area and dimensions
            chart = d3.select(".chart")
                .attr("width", spaceForLabels + chartWidth + spaceForLegend)
                .attr("height", chartHeight);

            // Create bars
            bar = chart.selectAll("g")
                .data(zippedData)
                .enter().append("g")
                .attr("transform", function (d, i) {
                    return "translate(" + spaceForLabels + "," + (i * barHeight + gapBetweenGroups * (0.5 + Math.floor(i / data.series.length))) + ")";
                });
        }

        function drawBarChart() {

            setChartParameters();

            // Create rectangles of the correct width
            bar.append("rect")
                .attr("fill", function (d, i) {
                    return color(i);
                })
                .attr("class", "bar")
                .attr("width", x)
                .attr("height", barHeight - 1);

            // Add text label in bar
            bar.append("text")
                .attr("x", function (d) {
                    return x(d) - (-30);
                })
                .attr("y", barHeight / 2)
                .attr("fill", "red")
                .attr("dy", ".35em")
                .text(function (d) {
                    return d;
                });

            // Draw labels
            bar.append("text")
                .attr("class", "label")
                .attr("x", function (d) {
                    return -10;
                })
                .attr("y", groupHeight / 2)
                .attr("dy", ".35em")
                .text(function (d, i) {
                    if (i % data.series.length === 0) {
                        return data.labels[Math.floor(i / data.series.length)];
                    } else {
                        return "";
                    }
                });

            chart.append("g")
                .attr("class", "y axis")
                .attr("transform", "translate(" + spaceForLabels + ", " + -gapBetweenGroups / 2 + ")")
                .call(yAxis);
        }

        drawBarChart();

            }    
        };

    });

问题是,当我在HTML中引用该指令两次时,如下所示:

代码语言:javascript
复制
<bar-chart chart-data="chartData"></bar-chart>
<bar-chart chart-data="chartData"></bar-chart>

该图表只创建一次(创建了第二个图表元素,但没有生成图表。

而且,即使我尝试创建另一个名称不同但代码和模板相同的指令,第一个指令和第二个指令也不能工作。

代码语言:javascript
复制
<bar-chart chart-data="chartData"></bar-chart>
<bar-chart2 chart-data="chartData"></bar-chart2>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-13 09:01:35

正如您在链接中所看到的,您必须从指令的元素参数中获取svg元素。检查这个柱塞https://plnkr.co/edit/TlTJWDfTPAWa1sDPQM7w?p=preview (很抱歉有宽度和x的问题)。在柱塞中,我得到svg元素如下:

代码语言:javascript
复制
chart = d3.select(rawSvg[0])...

而不是

代码语言:javascript
复制
chart = d3.select(".chart")...

有了这个,您可以放置多个图表。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37749209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档