0

我在服务器端应用程序上使用 Node 来动态生成图表。我正在使用 d3.js 和 rickshaw.js 创建图形的 SVG 版本,并使用 imagemagick 将该 SVG 转换为 png。我使用 JSDOM 作为我的 DOM。

我收到此错误:https ://github.com/shutterstock/rickshaw/issues/186

这里给出的解决方案是引入 css,我找到了关于如何使用 JSDOM 执行此操作的堆栈溢出的答案:

你如何将样式表广告到 JSDOM

所以我遵循了这些说明,并引入了 rickshaw.css。当我将 DOM 打印到控制台时,我可以在头部的样式元素中看到它。

var mainCss = fs.readFileSync(path.normalize("rickshaw.css"), 'utf8');
console.log("mainCss",mainCss);
var document = jsdom.jsdom("<!DOCTYPE html><html><meta http-equiv=\"content-type\"content=\"text/html; charset=utf-8\"><head></head><body id=\"abody\"><div id=\"chart_container\"><div id=\"y_axis\"></div><div id=\"chart\"></div></div></body></html>", jsdom.level(3, 'index'), {
    features : {
        FetchExternalResources : ['script', 'css'],
        QuerySelector : true
    }
});     

GLOBAL.window = document.parentWindow;
var head = document.getElementsByTagName('head')[0];
style = document.createElement("style");
style.type = 'text/css';
style.innerHTML = mainCss;
head.appendChild(style);

我正在设置我的图表:

var graph = new Rickshaw.Graph( {
element: document.querySelector('#chart'), 
    width: 600, 
    height: 600, 
    series: seriesArr
});

var yAxis = new Rickshaw.Graph.Axis.Y({
    graph: graph
});

var xAxis = new Rickshaw.Graph.Axis.Time({
    graph: graph,
    timeUnit: "hour"
});


yAxis.render();
xAxis.render();

graph.render();

utils.convertSVGtoPNG(document.querySelector('#chart').innerHTML);

我仍然得到一个黑色方块,作为我的输出 SVG。

我错过了什么吗?我在想什么不对吗?任何帮助将不胜感激。

4

2 回答 2

2

不幸的是,看起来 imagemagick 不支持外部 CSS并且其他寻求类似问题解决方案的人没有收到任何替代工具的建议。因此,您必须确保内联应用相关样式,以便您的 SVG 到 PNG 转换器能够识别它们。

执行此操作的通用方法是编写一个遍历CSS-DOM的脚本,获取每个规则,选择与规则匹配的所有元素,并将相应的样式作为内联样式应用于它们。

但是,对于您的需求,这可能是矫枉过正。您的具体问题是由<path>元素的默认样式引起的,即纯黑色填充且没有描边。当使用网格线时,这意味着轴域路径被绘制为一个覆盖整个绘图区域的实心黑色矩形。

因此,简单的解决方案是在绘制轴后选择这些路径,并直接应用自定义样式:

d3.selectAll("path.domain")
  .style({ fill:"none",
           stroke:"black",
           stroke-width:1,
        });
于 2014-02-25T16:53:32.537 回答
0

如果有人对复制所有 css 的 d3 选择器感兴趣,按照 Amelia 的推荐,他们是:

    d3.selectAll("path.domain")
  .style({ "fill":"none",
           "stroke":"black",
           "stroke-width":1
        });

d3.selectAll("path.domain")
    .style({
    "fill": "none",
        "stroke": "black",
        "stroke-width": "1"
});

d3.selectAll(".rickshaw_graph .detail")
    .style({
    "pointer-events": "none",
        "position": "absolute",
        "top": "0",
        "z-index": "2",
        "background": "rgba(0, 0, 0, 0.1)",
        "bottom": "0",
        "width": "1px",
        "transition": "opacity 0.25s linear",
        "-moz-transition": "opacity 0.25s linear",
        "-o-transition": "opacity 0.25s linear",
        "-webkit-transition": "opacity 0.25s linear"
});

d3.selectAll(".rickshaw_graph .detail.inactive ")
    .style({
    "opacity": "0"
});

d3.selectAll(".rickshaw_graph .detail .item.active ")
    .style({
    "opacity": "1"
});
d3.selectAll(".rickshaw_graph .detail .x_label ")
    .style({
    "font-family": "Arial, sans-serif",
        "border-radius": "3px",
        "padding": "6px",
        "opacity": "0.5",
        "border": "1px solid #e0e0e0",
        "font-size": "12px",
        "position": "absolute",
        "background": "white",
        "white-space": "nowrap"
});
d3.selectAll(".rickshaw_graph .detail .x_label.left ")
    .style({
    "left": "0"
});
d3.selectAll(".rickshaw_graph .detail .x_label.right ")
    .style({
    "right": "0"
});
d3.selectAll(".rickshaw_graph .detail .item ")
    .style({
    "position": "absolute",
        "z-index": "2",
        "border-radius": "3px",
        "padding": "0.25em",
        "font-size": "12px",
        "font-family": "Arial, sans-serif",
        "opacity": "0",
        "background": "rgba(0, 0, 0, 0.4)",
        "color": "white",
        "border": "1px solid rgba(0, 0, 0, 0.4)",
        "margin-left": "1em",
        "margin-right": "1em",
        "margin-top": "-1em",
        "white-space": "nowrap"
});
d3.selectAll(".rickshaw_graph .detail .item.left ")
    .style({
    "left": "0"
});
d3.selectAll(".rickshaw_graph .detail .item.right ")
    .style({
    "right": "0"
});
d3.selectAll(".rickshaw_graph .detail .item.active ")
    .style({
    "opacity": "1",
        "background": "rgba(0, 0, 0, 0.8)"
});

d3.selectAll(".rickshaw_graph .detail .dot ")
    .style({
    "width": "4px",
        "height": "4px",
        "margin-left": "-2px",
        "margin-top": "-2px",
        "border-radius": "5px",
        "position": "absolute",
        "box-shadow": "0 0 2px rgba(0, 0, 0, 0.6)",
        "background": "white",
        "border-width": "2px",
        "border-style": "solid",
        "display": "none",
        "background-clip": "padding-box"
});
d3.selectAll(".rickshaw_graph .detail .dot.active ")
    .style({
    "display": "block"
});
/* graph */

d3.selectAll(".rickshaw_graph ")
    .style({
    "position": "relative"
});
d3.selectAll(".rickshaw_graph svg ")
    .style({
    "display": "block",
        "overflow": "hidden"
});


d3.selectAll(".rickshaw_graph .x_tick ")
    .style({
    "position": "absolute",
        "top": "0",
        "bottom": "0",
        "width": "0px",
        "border-left": "1px dotted rgba(0, 0, 0, 0.2)",
        "pointer-events": "none"
});
d3.selectAll(".rickshaw_graph .x_tick .title ")
    .style({
    "position": "absolute",
        "font-size": "12px",
        "font-family": "Arial, sans-serif",
        "opacity": "0.5",
        "white-space": "nowrap",
        "margin-left": "3px",
        "bottom": "1px"
});


d3.selectAll(".rickshaw_annotation_timeline ")
    .style({
    "height": "1px",
        "border-top": "1px solid #e0e0e0",
        "margin-top": "10px",
        "position": "relative"
});
d3.selectAll(".rickshaw_annotation_timeline .annotation ")
    .style({
    "position": "absolute",
        "height": "6px",
        "width": "6px",
        "margin-left": "-2px",
        "top": "-3px",
        "border-radius": "5px",
        "background-color": "rgba(0, 0, 0, 0.25)"
});
d3.selectAll(".rickshaw_graph .annotation_line ")
    .style({
    "position": "absolute",
        "top": "0",
        "bottom": "-6px",
        "width": "0px",
        "border-left": "2px solid rgba(0, 0, 0, 0.3)",
        "display": "none"
});
d3.selectAll(".rickshaw_graph .annotation_line.active ")
    .style({
    "display": "block"
});

d3.selectAll(".rickshaw_graph .annotation_range ")
    .style({
    "background": "rgba(0, 0, 0, 0.1)",
    "display": "none",
    "position": "absolute",
    "top": "0",
    "bottom": "-6px"
});
d3.selectAll(".rickshaw_graph .annotation_range.active ")
    .style({
    "display": "block"
});
d3.selectAll(".rickshaw_graph .annotation_range.active.offscreen ")
    .style({
    "display": "none"
});

d3.selectAll(".rickshaw_annotation_timeline .annotation .content ")
    .style({
    "background": "white",
        "color": "black",
        "opacity": "0.9",
        "padding": "5px 5px",
        "box-shadow": "0 0 2px rgba(0, 0, 0, 0.8)",
        "border-radius": "3px",
        "position": "relative",
        "z-index": "20",
        "font-size": "12px",
        "top": "18px",
        "left": "-11px",
        "width": "160px",
        "display": "none",
        "cursor": "pointer"
});



d3.selectAll(".rickshaw_annotation_timeline .annotation.active .content ")
    .style({
    "display": "block"
});
d3.selectAll(".rickshaw_annotation_timeline .annotation:hover .content ")
    .style({
    "display": "block",
        "z-index": "50"
});
d3.selectAll(".rickshaw_graph .y_axis, .rickshaw_graph  .x_axis_d3 ")
    .style({
    "fill": "none"
});
d3.selectAll(".rickshaw_graph .y_ticks .tick, .rickshaw_graph .x_ticks_d3 .tick ")
    .style({
    "stroke": "rgba(0, 0, 0, 0.16)",
        "stroke-width": "2px",
        "shape-rendering": "crisp-edges",
        "pointer-events": "none"
});

d3.selectAll(".rickshaw_graph .y_grid .tick, .rickshaw_graph .x_grid_d3 .tick ")
    .style({
    "z-index": "-1",
        "stroke": "rgba(0, 0, 0, 0.20)",
        "stroke-width": "1px",
        "stroke-dasharray": "1 1"
});
d3.selectAll(".rickshaw_graph .y_grid .tick[data-y-value=\"0\"] ")
    .style({
    "stroke-dasharray": "1 0"
});
d3.selectAll(".rickshaw_graph .y_grid path,.rickshaw_graph .x_grid_d3 path  ")
    .style({
    "fill": "none",
        "stroke": "none"
});
d3.selectAll(".rickshaw_graph .y_ticks path, .rickshaw_graph .x_ticks_d3 path ")
    .style({
    "fill": "none",
        "stroke": "#808080"
});
d3.selectAll(".rickshaw_graph .y_ticks text, .rickshaw_graph .x_ticks_d3 text ")
    .style({
    "opacity": "0.5",
        "font-size": "12px",
        "pointer-events": "none"
});
d3.selectAll(".rickshaw_graph .x_tick.glow .title, .rickshaw_graph .y_ticks.glow text ")
    .style({
    "fill": "black",
        "color": "black",
        "text-shadow":
        "-1px 1px 0 rgba(255, 255, 255, 0.1),1px -1px 0 rgba(255, 255, 255, 0.1),1px 1px 0 rgba(255, 255, 255, 0.1),0px 1px 0 rgba(255, 255, 255, 0.1),0px -1px 0 rgba(255, 255, 255, 0.1),1px 0px 0 rgba(255, 255, 255, 0.1),-1px 0px 0 rgba(255, 255, 255, 0.1),-1px -1px 0 rgba(255, 255, 255, 0.1)"
});

d3.selectAll(".rickshaw_graph .x_tick.inverse .title, .rickshaw_graph .y_ticks.inverse text")
    .style({
    "fill": "white",
        "color": "white",
        "text-shadow": "-1px 1px 0 rgba(0, 0, 0, 0.8),1px -1px 0 rgba(0, 0, 0, 0.8),1px 1px 0 rgba(0, 0, 0, 0.8),0px 1px 0 rgba(0, 0, 0, 0.8),0px -1px 0 rgba(0, 0, 0, 0.8),1px 0px 0 rgba(0, 0, 0, 0.8),-1px 0px 0 rgba(0, 0, 0, 0.8),-1px -1px 0 rgba(0, 0, 0, 0.8)"
});
d3.selectAll(".rickshaw_legend ")
    .style({
    "font-family": "Arial",
        "font-size": "12px",
        "color": "white",
        "background": "#404040",
        "display": "inline-block",
        "padding": "12px 5px",
        "border-radius": "2px",
        "position": "relative"
});

d3.selectAll(".rickshaw_legend .swatch ")
    .style({
    "width": "10px",
        "height": "10px",
        "border": "1px solid rgba(0, 0, 0, 0.2)"
});
d3.selectAll(".rickshaw_legend .line ")
    .style({
    "clear": "both",
        "line-height": "140%",
        "padding-right": "15px"
});
d3.selectAll(".rickshaw_legend .line .swatch ")
    .style({
    "display": "inline-block",
        "margin-right": "3px",
        "border-radius": "2px"
});
d3.selectAll(".rickshaw_legend .label ")
    .style({
    "margin": "0",
        "white-space": "nowrap",
        "display": "inline",
        "font-size": "inherit",
        "background-color": "transparent",
        "color": "inherit",
        "font-weight": "normal",
        "line-height": "normal",
        "padding": "0px",
        "text-shadow": "none"
});

d3.selectAll(".rickshaw_legend .action ")
    .style({
    "margin-right": "0.2em",
        "font-size": "10px",
        "opacity": "0.2",
        "cursor": "pointer"
});
d3.selectAll(".rickshaw_legend .line.disabled ")
    .style({
    "opacity": "0.4"
});
d3.selectAll(".rickshaw_legend ul ")
    .style({
    "list-style-type": "none",
        "margin": "0",
        "padding": "0",
            "cursor": "pointer"
    });
    d3.selectAll(".rickshaw_legend li ")
        .style({
        "padding": "0 0 0 2px",
            "min-width": "80px",
            "white-space": "nowrap"
    });

它的格式不正确,我不得不删除任何具有伪选择器的类。

于 2014-02-25T18:33:22.800 回答