D3js Экспорт SVG в изображение - PullRequest
0 голосов
/ 23 мая 2018

У меня есть этот D3js линейный график , с которым я работаю.

Я бы хотел сохранить его как изображение в том же каталоге, как показано в этот пример

d3.select('#saveButton').on('click', function(){
    var svgString = getSVGString(svg.node());
    svgString2Image( svgString, 2*width, 2*height, 'png', save ); // passes Blob and filesize String to the callback

    function save( dataBlob, filesize ){
        saveAs( dataBlob, 'D3 vis exported to PNG.png' ); // FileSaver.js 
function
    }
});

без ошибок при выполнении вышеуказанного

Хотя я не получаю ошибок, файл не загружается при нажатии кнопки.Что мне здесь не хватает?Спасибо!

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

После просмотра getCSSStyles похоже, что он проверяет только те правила, которые точно соответствуют идентификатору или классу корневого svg и его дочерних элементов.Я думаю, что это более щадящая реализация:

function getCSSStyles( parentElement ) {
    var nodesToCheck = [ parentElement ], i;

    // Add all the different nodes to check
    var childNodes = parentElement.getElementsByTagName("*");
    for (i = 0; i < childNodes.length; i++) {
        nodesToCheck.push(childNodes[i]);
    }

    // Extract CSS Rules
    var extractedCSSRules = [];
    for (i = 0; i < document.styleSheets.length; i++) {
        var s = document.styleSheets[i];

        try {
            if (!s.cssRules) continue;
        } catch( e ) {
            if (e.name !== 'SecurityError') throw e; // for Firefox
            continue;
        }

        var cssRules = s.cssRules;
        var ruleMatches;
        for (var r = 0; r < cssRules.length; r++) {
            ruleMatches = nodesToCheck.reduce(function (a, b) {
                return a || b.matches(cssRules[r].selectorText);
            }, false);
            if (ruleMatches)
                extractedCSSRules.push(cssRules[r].cssText);
        }
    }
    return extractedCSSRules.join(' ');
}

Вам все еще нужно использовать внутренние правила для svg (например, вам все еще нужно изменить #priceWithMilestones .line на .line в CSS), но на будущеепроекты, я думаю, что это должно поймать больше элементов.

Обновлена ​​скрипка со всеми изменениями: https://jsfiddle.net/c19664p3/12/

0 голосов
/ 23 мая 2018

В скрипте вы добавляете g к вашему svg и присваиваете ему свою переменную svg:

var svg = d3.select("#priceWithMilestones")
  .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 + ")");

Похоже, getSVGString() ожидает корневой узел, а неg элемент.Вам, вероятно, следует изменить свой код так, чтобы svg отражал корневой элемент svg, и создать другую переменную для хранения элемента g, но для быстрого и грязного исправления вы можете изменить

var svgString = getSVGString(svg.node());

на

var svgString = getSVGString(d3.select('svg').node());

И следует сохранить.Обновленная скрипка: https://jsfiddle.net/c19664p3/8/

Редактировать: Что касается экспортированных стилей, похоже, что вы не можете ссылаться на селекторы вне svg при объявлении выбора.Кроме того, похоже, что он должен состоять только из идентификатора или класса.Смотрите мой другой ответ для более слабого экспортера правил CSS.

Итак, изменив это:

#priceWithMilestones .line {
  fill: none;
  stroke: #14da9e;
  stroke-width: 2px;
}

на:

.line {
  fill: none;
  stroke: #14da9e;
  stroke-width: 2px;
}

экспортирует стиль линии только для svg,Обновленная скрипка: https://jsfiddle.net/c19664p3/10/

...